<commit_before>/*
    This file is part of KMail.
    Copyright (c) 2002-2003 Don Sanders <sanders@kde.org>,
    Copyright (c) 2003      Zack Rusin  <zack@kde.org>,
    Based on the work of Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "kmail_part.h"

#include "kmmainwin.h"
#include "kmmainwidget.h"
#include "kmfoldertree.h"
#include "kmstartup.h"
#include "kmbroadcaststatus.h"
#include "aboutdata.h"
#include "kmkernel.h"
#include "kmfolder.h"
#if KDE_IS_VERSION( 3, 1, 90 )
#include "sidebarextension.h"
#include "infoextension.h"
#endif

#include <kapplication.h>
#include <kparts/genericfactory.h>
#include <knotifyclient.h>
#include <dcopclient.h>
#include <kiconloader.h>
#include <kdebug.h>

#include <qlayout.h>

typedef KParts::GenericFactory< KMailPart > KMailFactory;
K_EXPORT_COMPONENT_FACTORY( libkmailpart, KMailFactory );

KMailPart::KMailPart(QWidget *parentWidget, const char *widgetName,
		     QObject *parent, const char *name, const QStringList &) :
  DCOPObject("KMailIface"), KParts::ReadOnlyPart(parent, name),
  mParentWidget( parentWidget )
{
  kdDebug(5006) << "KMailPart()" << endl;
  kdDebug(5006) << "  InstanceName: " << kapp->instanceName() << endl;

  setInstance(KMailFactory::instance());

  kdDebug(5006) << "KMailPart()..." << endl;
  kdDebug(5006) << "  InstanceName: " << kapp->instanceName() << endl;

  KGlobal::locale()->insertCatalogue("libkdenetwork");

  // Check that all updates have been run on the config file:
  KMail::checkConfigUpdates();

  // Make sure that the KNotify Daemon is running (this is necessary for people
  // using KMail without KDE)
  KNotifyClient::startDaemon();

  KMail::lockOrDie();

  kapp->dcopClient()->suspend(); // Don't handle DCOP requests yet

  //local, do the init
  KMKernel *kmailKernel = new KMKernel();
  kmailKernel->init();
  kmailKernel->setXmlGuiInstance( KMailFactory::instance() );

  // Will this cause trouble? Comment it out just in case
  // Yes, it's wrong in kontact... (DF)
  //kapp->dcopClient()->setDefaultObject( kmailKernel->objId() );

  // and session management
  kmailKernel->doSessionManagement();

  // any dead letters?
  kmailKernel->recoverDeadLetters();

  kmsetSignalHandler(kmsignalHandler);
  kapp->dcopClient()->resume(); // Ok. We are ready for DCOP requests.

  // create a canvas to insert our widget
  QWidget *canvas = new QWidget(parentWidget, widgetName);
  canvas->setFocusPolicy(QWidget::ClickFocus);
  setWidget(canvas);
  KGlobal::iconLoader()->addAppDir("kmail");
#if 0
  //It's also possible to make a part out of a readerWin
  KMReaderWin *mReaderWin = new KMReaderWin( canvas, canvas, actionCollection() );
  connect(mReaderWin, SIGNAL(urlClicked(const KURL&,int)),
	  mReaderWin, SLOT(slotUrlClicked()));
  QVBoxLayout *topLayout = new QVBoxLayout(canvas);
  topLayout->addWidget(mReaderWin);
  mReaderWin->setAutoDelete( true );
  kernel->inboxFolder()->open();
  KMMessage *msg = kernel->inboxFolder()->getMsg(0);
  mReaderWin->setMsg( msg, true );
  mReaderWin->setFocusPolicy(QWidget::ClickFocus);
  m_extension = new KMailBrowserExtension(this);
#if KDE_IS_VERSION( 3, 1, 90 )
  mStatusBar  = new KMailStatusBarExtension(this);
  mStatusBar->addStatusBarItem( mainWidget->progressDialog(), 0, true );
  //new KParts::SideBarExtension( kernel->mainWin()-mainKMWidget()->leftFrame(), this );
#endif
  KGlobal::iconLoader()->addAppDir("kmail");
  setXMLFile( "kmmainwin.rc" );
  kernel->inboxFolder()->close();
#else
  mainWidget = new KMMainWidget( canvas, "mainWidget", actionCollection());
  QVBoxLayout *topLayout = new QVBoxLayout(canvas);
  topLayout->addWidget(mainWidget);
  mainWidget->setFocusPolicy(QWidget::ClickFocus);
  m_extension = new KMailBrowserExtension(this);
#if KDE_IS_VERSION( 3, 1, 90 )
  mStatusBar  = new KMailStatusBarExtension(this);
  mStatusBar->addStatusBarItem( mainWidget->progressDialog(), 0, true );
  new KParts::SideBarExtension( mainWidget->folderTree(),
                                this,
                                "KMailSidebar" );

  // Get to know when the user clicked on a folder in the KMail part and update the headerWidget of Kontact
  KParts::InfoExtension *ie = new KParts::InfoExtension( this, "KMailInfo" );
  connect( mainWidget->folderTree(), SIGNAL(folderSelected(KMFolder*)), this, SLOT(exportFolder(KMFolder*)) );
  connect( mainWidget->folderTree(), SIGNAL(iconChanged(KMFolderTreeItem*)),
           this, SLOT(slotIconChanged(KMFolderTreeItem*)) );
  connect( mainWidget->folderTree(), SIGNAL(nameChanged(KMFolderTreeItem*)),
           this, SLOT(slotNameChanged(KMFolderTreeItem*)) );
  connect( this, SIGNAL(textChanged(const QString&)), ie, SIGNAL(textChanged(const QString&)) );
  connect( this, SIGNAL(iconChanged(const QPixmap&)), ie, SIGNAL(iconChanged(const QPixmap&)) );

#endif
  KGlobal::iconLoader()->addAppDir( "kmail" );
  setXMLFile( "kmmainwin.rc" );
#endif
}

KMailPart::~KMailPart()
{
  kernel->dumpDeadLetters();
  mainWidget->destruct();
  QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
  KMainWindow *window = 0;
  while ((window = it.current()) != 0) {
    ++it;
    if (window->inherits("KMTopLevelWidget"))
      window->close(TRUE);
  }
  kernel->notClosedByUser();
  delete kernel;
  KMail::cleanup();
}

KAboutData *KMailPart::createAboutData()
{
  return new KMail::AboutData();
}

bool KMailPart::openFile()
{
  kdDebug(5006) << "KMailPart:openFile()" << endl;

  mainWidget->show();
  return true;
}

void KMailPart::exportFolder( KMFolder *folder )
{
  KMFolderTreeItem* fti = static_cast< KMFolderTreeItem* >( mainWidget->folderTree()->currentItem() );

  if ( folder != 0 )
    emit textChanged( folder->label() );

  if ( fti )
    emit iconChanged( fti->normalIcon( 22 ) );
}

void KMailPart::slotIconChanged( KMFolderTreeItem *fti )
{
  emit iconChanged( fti->normalIcon( 22 ) );
}

void KMailPart::slotNameChanged( KMFolderTreeItem *fti )
{
  emit textChanged( fti->folder()->label() );
}

void KMailPart::guiActivateEvent(KParts::GUIActivateEvent *e)
{
  kdDebug(5006) << "KMailPart::guiActivateEvent" << endl;
  KParts::ReadOnlyPart::guiActivateEvent(e);
}

void KMailPart::exit()
{
  delete this;
}

QWidget* KMailPart::parentWidget() const
{
  return mParentWidget;
}

KMailBrowserExtension::KMailBrowserExtension(KMailPart *parent) :
  KParts::BrowserExtension(parent, "KMailBrowserExtension")
{
}

KMailBrowserExtension::~KMailBrowserExtension()
{
}

#if KDE_IS_VERSION( 3, 1, 90 )
KMailStatusBarExtension::KMailStatusBarExtension( KMailPart *parent )
  : KParts::StatusBarExtension( parent ), mParent( parent )
{
}

KMainWindow * KMailStatusBarExtension::mainWindow() const
{
  return static_cast<KMainWindow*>( mParent->parentWidget() );
}

#endif

#include "kmail_part.moc"

<commit_msg>KMail currently does not cleanup when closed from kontact. This remedies that. Don, Zack, is this ok?<commit_after>/*
    This file is part of KMail.
    Copyright (c) 2002-2003 Don Sanders <sanders@kde.org>,
    Copyright (c) 2003      Zack Rusin  <zack@kde.org>,
    Based on the work of Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "kmail_part.h"

#include "kmmainwin.h"
#include "kmmainwidget.h"
#include "kmfoldertree.h"
#include "kmstartup.h"
#include "kmbroadcaststatus.h"
#include "aboutdata.h"
#include "kmkernel.h"
#include "kmfolder.h"
#if KDE_IS_VERSION( 3, 1, 90 )
#include "sidebarextension.h"
#include "infoextension.h"
#endif

#include <kapplication.h>
#include <kparts/genericfactory.h>
#include <knotifyclient.h>
#include <dcopclient.h>
#include <kiconloader.h>
#include <kdebug.h>

#include <qlayout.h>

typedef KParts::GenericFactory< KMailPart > KMailFactory;
K_EXPORT_COMPONENT_FACTORY( libkmailpart, KMailFactory );

KMailPart::KMailPart(QWidget *parentWidget, const char *widgetName,
		     QObject *parent, const char *name, const QStringList &) :
  DCOPObject("KMailIface"), KParts::ReadOnlyPart(parent, name),
  mParentWidget( parentWidget )
{
  kdDebug(5006) << "KMailPart()" << endl;
  kdDebug(5006) << "  InstanceName: " << kapp->instanceName() << endl;

  setInstance(KMailFactory::instance());

  kdDebug(5006) << "KMailPart()..." << endl;
  kdDebug(5006) << "  InstanceName: " << kapp->instanceName() << endl;

  KGlobal::locale()->insertCatalogue("libkdenetwork");

  // Check that all updates have been run on the config file:
  KMail::checkConfigUpdates();

  // Make sure that the KNotify Daemon is running (this is necessary for people
  // using KMail without KDE)
  KNotifyClient::startDaemon();

  KMail::lockOrDie();

  kapp->dcopClient()->suspend(); // Don't handle DCOP requests yet

  //local, do the init
  KMKernel *kmailKernel = new KMKernel();
  kmailKernel->init();
  kmailKernel->setXmlGuiInstance( KMailFactory::instance() );

  // Will this cause trouble? Comment it out just in case
  // Yes, it's wrong in kontact... (DF)
  //kapp->dcopClient()->setDefaultObject( kmailKernel->objId() );

  // and session management
  kmailKernel->doSessionManagement();

  // any dead letters?
  kmailKernel->recoverDeadLetters();

  kmsetSignalHandler(kmsignalHandler);
  kapp->dcopClient()->resume(); // Ok. We are ready for DCOP requests.

  // create a canvas to insert our widget
  QWidget *canvas = new QWidget(parentWidget, widgetName);
  canvas->setFocusPolicy(QWidget::ClickFocus);
  setWidget(canvas);
  KGlobal::iconLoader()->addAppDir("kmail");
#if 0
  //It's also possible to make a part out of a readerWin
  KMReaderWin *mReaderWin = new KMReaderWin( canvas, canvas, actionCollection() );
  connect(mReaderWin, SIGNAL(urlClicked(const KURL&,int)),
	  mReaderWin, SLOT(slotUrlClicked()));
  QVBoxLayout *topLayout = new QVBoxLayout(canvas);
  topLayout->addWidget(mReaderWin);
  mReaderWin->setAutoDelete( true );
  kernel->inboxFolder()->open();
  KMMessage *msg = kernel->inboxFolder()->getMsg(0);
  mReaderWin->setMsg( msg, true );
  mReaderWin->setFocusPolicy(QWidget::ClickFocus);
  m_extension = new KMailBrowserExtension(this);
#if KDE_IS_VERSION( 3, 1, 90 )
  mStatusBar  = new KMailStatusBarExtension(this);
  mStatusBar->addStatusBarItem( mainWidget->progressDialog(), 0, true );
  //new KParts::SideBarExtension( kernel->mainWin()-mainKMWidget()->leftFrame(), this );
#endif
  KGlobal::iconLoader()->addAppDir("kmail");
  setXMLFile( "kmmainwin.rc" );
  kernel->inboxFolder()->close();
#else
  mainWidget = new KMMainWidget( canvas, "mainWidget", actionCollection());
  QVBoxLayout *topLayout = new QVBoxLayout(canvas);
  topLayout->addWidget(mainWidget);
  mainWidget->setFocusPolicy(QWidget::ClickFocus);
  m_extension = new KMailBrowserExtension(this);
#if KDE_IS_VERSION( 3, 1, 90 )
  mStatusBar  = new KMailStatusBarExtension(this);
  mStatusBar->addStatusBarItem( mainWidget->progressDialog(), 0, true );
  new KParts::SideBarExtension( mainWidget->folderTree(),
                                this,
                                "KMailSidebar" );

  // Get to know when the user clicked on a folder in the KMail part and update the headerWidget of Kontact
  KParts::InfoExtension *ie = new KParts::InfoExtension( this, "KMailInfo" );
  connect( mainWidget->folderTree(), SIGNAL(folderSelected(KMFolder*)), this, SLOT(exportFolder(KMFolder*)) );
  connect( mainWidget->folderTree(), SIGNAL(iconChanged(KMFolderTreeItem*)),
           this, SLOT(slotIconChanged(KMFolderTreeItem*)) );
  connect( mainWidget->folderTree(), SIGNAL(nameChanged(KMFolderTreeItem*)),
           this, SLOT(slotNameChanged(KMFolderTreeItem*)) );
  connect( this, SIGNAL(textChanged(const QString&)), ie, SIGNAL(textChanged(const QString&)) );
  connect( this, SIGNAL(iconChanged(const QPixmap&)), ie, SIGNAL(iconChanged(const QPixmap&)) );

#endif
  KGlobal::iconLoader()->addAppDir( "kmail" );
  setXMLFile( "kmmainwin.rc" );
#endif
}

KMailPart::~KMailPart()
{
  kernel->dumpDeadLetters();
  mainWidget->destruct();
  QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
  KMainWindow *window = 0;
  while ((window = it.current()) != 0) {
    ++it;
    if (window->inherits("KMTopLevelWidget"))
      window->close(TRUE);
  }
  kernel->cleanup();
  delete kernel;
  KMail::cleanup();
}

KAboutData *KMailPart::createAboutData()
{
  return new KMail::AboutData();
}

bool KMailPart::openFile()
{
  kdDebug(5006) << "KMailPart:openFile()" << endl;

  mainWidget->show();
  return true;
}

void KMailPart::exportFolder( KMFolder *folder )
{
  KMFolderTreeItem* fti = static_cast< KMFolderTreeItem* >( mainWidget->folderTree()->currentItem() );

  if ( folder != 0 )
    emit textChanged( folder->label() );

  if ( fti )
    emit iconChanged( fti->normalIcon( 22 ) );
}

void KMailPart::slotIconChanged( KMFolderTreeItem *fti )
{
  emit iconChanged( fti->normalIcon( 22 ) );
}

void KMailPart::slotNameChanged( KMFolderTreeItem *fti )
{
  emit textChanged( fti->folder()->label() );
}

void KMailPart::guiActivateEvent(KParts::GUIActivateEvent *e)
{
  kdDebug(5006) << "KMailPart::guiActivateEvent" << endl;
  KParts::ReadOnlyPart::guiActivateEvent(e);
}

void KMailPart::exit()
{
  delete this;
}

QWidget* KMailPart::parentWidget() const
{
  return mParentWidget;
}

KMailBrowserExtension::KMailBrowserExtension(KMailPart *parent) :
  KParts::BrowserExtension(parent, "KMailBrowserExtension")
{
}

KMailBrowserExtension::~KMailBrowserExtension()
{
}

#if KDE_IS_VERSION( 3, 1, 90 )
KMailStatusBarExtension::KMailStatusBarExtension( KMailPart *parent )
  : KParts::StatusBarExtension( parent ), mParent( parent )
{
}

KMainWindow * KMailStatusBarExtension::mainWindow() const
{
  return static_cast<KMainWindow*>( mParent->parentWidget() );
}

#endif

#include "kmail_part.moc"

<|endoftext|>


<commit_before>#include <pylon_camera/pylon_camera_opencv_node.h>

using namespace std;

namespace pylon_camera
{

PylonCameraOpenCVNode::PylonCameraOpenCVNode() :
                    cv_img_rect_(),
                    cv_img_seq_(),
                    cv_img_hdr_(),
                    exp_times_(),
                    img_rect_pub_(nh_.advertise<sensor_msgs::Image>("image_rect", 10)),
                    img_seq_pub_(nh_.advertise<sensor_msgs::Image>("image_seq", 10)),
                    img_hdr_pub_(nh_.advertise<sensor_msgs::Image>("image_hdr", 10)),
                    exp_times_pub_(nh_.advertise<pylon_camera_msgs::SequenceExposureTimes>("seq_exp_times", 10)),
                    img_rectifier_(),
                    calib_loader_(),
                    img_raw_()
{
}

void PylonCameraOpenCVNode::getInitialCameraParameter()
{
    PylonCameraNode::getInitialCameraParameter();

    nh_.param<bool>("use_sequencer", params_.use_sequencer_, false);
    if (params_.use_sequencer_)
    {
        nh_.getParam("desired_seq_exp_times", params_.desired_seq_exp_times_);
        image_sequence_.resize(params_.desired_seq_exp_times_.size());
        //assert(params_.desired_seq_exp_times_.size() == 3);

        nh_.param<bool>("output_hdr_img", params_.output_hdr_, false);
    }

    nh_.param<std::string>("intrinsic_yaml_string",
                           params_.intrinsic_yaml_file_,
                           "INVALID_YAML_FILE");

    if (params_.intrinsic_yaml_file_ == "INVALID_YAML_FILE")
    {
        ROS_WARN("Yaml file string needed for rectification! Param: 'pylon_camera_node/intrinsic_yaml_string' has entry: %s",
                 params_.intrinsic_yaml_file_.c_str());
        ROS_WARN("Alternative: Get only distorted image by compiling 'WITHOUT_OPENCV'");
        ROS_INFO("Will only provide image_raw!");
        params_.have_intrinsic_data_ = false;
        if(params_.use_sequencer_){
            ROS_WARN("Sequencer-Mode needs intrinsic data! Will disable sequencer!");
            params_.use_sequencer_ =  false;
            params_.output_hdr_ = false;
        }
    }
}

uint32_t PylonCameraOpenCVNode::getNumSubscribers() const
{
    return img_raw_pub_.getNumSubscribers() + img_rect_pub_.getNumSubscribers()
         + img_seq_pub_.getNumSubscribers()
         + img_hdr_pub_.getNumSubscribers();
}

uint32_t PylonCameraOpenCVNode::getNumSubscribersRaw() const
{
    return img_raw_pub_.getNumSubscribers();
}

uint32_t PylonCameraOpenCVNode::getNumSubscribersRect() const
{
    return img_rect_pub_.getNumSubscribers();
}
uint32_t PylonCameraOpenCVNode::getNumSubscribersSeq() const
{
    return img_seq_pub_.getNumSubscribers();
}
uint32_t PylonCameraOpenCVNode::getNumSubscribersHdr() const
{
    return img_hdr_pub_.getNumSubscribers();
}
bool PylonCameraOpenCVNode::init()
{

    if (!PylonCameraNode::initAndRegister())
    {
        return false;
    }

    if (params_.use_sequencer_)
    {
        pylon_camera_->setupSequencer(params_.desired_seq_exp_times_);
    }

    if (!PylonCameraNode::startGrabbing())
    {
        return false;
    }

    cv_img_rect_.header = img_raw_msg_.header;
    cv_img_seq_.header = img_raw_msg_.header;
    cv_img_hdr_.header = img_raw_msg_.header;
    exp_times_.header = img_raw_msg_.header;
    // Encoding of pixels -- channel meaning, ordering, size
    // taken from the list of strings in include/sensor_msgs/image_encodings.h
    cv_img_rect_.encoding = pylon_camera_->imageEncoding();
    cv_img_seq_.encoding = sensor_msgs::image_encodings::BGR8;
    cv_img_hdr_.encoding = pylon_camera_->imageEncoding();

    cv_img_hdr_.image  = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC1);
    cv_img_seq_.image  = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC3);
    cv_img_rect_.image = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC1);

    if (params_.use_sequencer_)
    {
        for (std::size_t i = 0; i < params_.desired_seq_exp_times_.size(); ++i)
        {
            image_sequence_[i] = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC1);
            exp_times_.exp_times.data.push_back(params_.desired_seq_exp_times_[i]);
        }
    }

    calib_loader_.init(params_.intrinsic_yaml_file_);

    if (!calib_loader_.loadCalib())
    {
        params_.have_intrinsic_data_ = false;
        cerr << "Error reading intrinsic calibration from yaml file!" << endl;
    }
    if (calib_loader_.img_cols() != (int)img_raw_msg_.width || calib_loader_.img_rows()
                                                          != (int)img_raw_msg_.height)
    {
        cerr << "Error: Image size from yaml file (" << calib_loader_.img_cols() << ", "
             << calib_loader_.img_rows()
             << ") does not match to the size of the connected camera ("
             << img_raw_msg_.width
             << ", " << img_raw_msg_.height << ")! Will publish only raw image!" << endl;
        params_.have_intrinsic_data_ = false;
        if(params_.use_sequencer_){
            ROS_WARN("Sequencer-Mode needs intrinsic data! Will disable sequencer!");
            params_.use_sequencer_ =  false;
            params_.output_hdr_ = false;
        }
    }
    else
    {
        params_.have_intrinsic_data_ = true;
        setupCameraInfoMsg();
        img_rectifier_.setupRectifyingMap(calib_loader_.K(),
                                          calib_loader_.D(),
                                          pylon_camera_->imageCols(),
                                          pylon_camera_->imageRows());
    }

    return true;
}
void PylonCameraOpenCVNode::setupCameraInfoMsg()
{

    cam_info_msg_.distortion_model = "plumb_bob";
    cam_info_msg_.D.resize(5);

    for (uint i = 0; i < 5; ++i)
    {
        double d = calib_loader_.D().at<double>(0, i);
        cam_info_msg_.D[i] = d;
    }

    int pos = 0;
    for (uint i = 0; i < 3; ++i)
    {
        for (uint j = 0; j < 3; ++j)
        {
            cam_info_msg_.K[pos++] = calib_loader_.K().at<double>(i, j);
        }
    }

    pos = 0;
    for (uint i = 0; i < 3; ++i)
    {
        for (uint j = 0; j < 3; ++j)
        {
            cam_info_msg_.P[pos++] = calib_loader_.K().at<double>(i, j);
        }
        cam_info_msg_.P[pos++] = 0;
    }
    //	cam_info_msg_.P = 0.0;
    //	cam_info_msg_.R = 0.0;
    //	cam_info_msg_.binning_x =
    //	cam_info_msg_.binning_y =
    //	cam_info_msg_.roi =
}

bool PylonCameraOpenCVNode::grabImage()
{
    if (!PylonCameraNode::grabImage())
        return false;

    //img_raw_ = cv::Mat(pylon_camera_->img_rows(), pylon_camera_->img_cols(), CV_8UC1);

    //memcpy(img_raw_.ptr(), img_raw_msg_.data.data(), pylon_camera_->image_size());

    boost::lock_guard<boost::recursive_mutex> lock(grab_mutex_);
    img_raw_ = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC1, img_raw_msg_.data.data());

    if (pylon_camera_->isOwnBrightnessFunctionRunning())
    {
//        int c = pylon_camera_->img_cols(), r = pylon_camera_->img_rows();
//        pylon_opencv_interface_.exp_search_params_.current_brightness_ = cv::mean(img_raw_.colRange(0.25 * c, 0.75 * c)
//                        .rowRange(0.25 * r,
//                                  0.75 * r))
//                                            .val[0];
        pylon_camera_->exp_search_params_.current_brightness_ = cv::mean(img_raw_).val[0];
//        .colRange(0.25 * c, 0.75 * c)
//                        .rowRange(0.25 * r,
//                                  0.75 * r))
//                                            .val[0];
    }

    if (params_.have_intrinsic_data_)
    {
        cv_img_rect_.header = img_raw_msg_.header;
        img_rectifier_.rectify(img_raw_, cv_img_rect_.image);
    }

    return true;
}
bool PylonCameraOpenCVNode::grabSequence()
{
    boost::lock_guard<boost::recursive_mutex> lock(grab_mutex_);
    image_sequence_.resize(params_.desired_seq_exp_times_.size());
    bool success = true;
    std::size_t mid = params_.desired_seq_exp_times_.size() / 2;
    for (std::size_t i = 0; i < params_.desired_seq_exp_times_.size(); ++i)
    {
        if (!(pylon_camera_->grab(image_sequence_[i])))
        {
            if (pylon_camera_->isCamRemoved())
            {
                ROS_ERROR("Pylon Camera has been removed!");
                ros::shutdown();
            }
            else
            {
                ROS_ERROR("Pylon Interface returned NULL-Pointer!");
            }
            success = false;
        }
        if (i == mid && success)
        {
            if (getNumSubscribersRaw())
            {
                img_raw_msg_.data = std::vector<uint8_t>(image_sequence_[i].data,
                                                         image_sequence_[i].data + pylon_camera_->imageSize());
            }
            if (params_.have_intrinsic_data_)
            {
                if (getNumSubscribersRect())
                {
                    img_rectifier_.rectify(image_sequence_[i], cv_img_rect_.image);
                }
            }
        }
    }
    if (!success)
        return false;

    img_raw_msg_.header.stamp = ros::Time::now();
    cam_info_msg_.header.stamp = img_raw_msg_.header.stamp;
    cv_img_rect_.header = img_raw_msg_.header;
    cv_img_seq_.header.stamp = img_raw_msg_.header.stamp;
    exp_times_.header.stamp = img_raw_msg_.header.stamp;

    if (params_.output_hdr_)
    {
        if (getNumSubscribersHdr())
        {
            //ros::Time now = ros::Time::now();
            cv_img_hdr_.header.stamp = img_raw_msg_.header.stamp;
            if (!hdr_generator_.merge(image_sequence_, pylon_camera_->sequencerExposureTimes(), hdr_img_))
            {
                cerr << "Error while generating HDR image" << endl;
            }
            //ROS_INFO_STREAM("HDR TOOK " << (ros::Time::now() - now).toSec());
            img_rectifier_.rectify(hdr_img_, cv_img_hdr_.image);
        }
    }
    else
    {
        // I put this into the else clause of hdr as I don't think it makes sense to produce a psoido BGR image out of three grayscale images
        if (getNumSubscribersSeq() && image_sequence_.size() == 3)
        {
            cv::Mat img_seq_bgr;
            cv::merge(image_sequence_.data(), 3, img_seq_bgr);

            img_rectifier_.rectify(img_seq_bgr, cv_img_seq_.image);
        }
    }

    return true;
}

PylonCameraOpenCVNode::~PylonCameraOpenCVNode()
{
}

}
<commit_msg>reduced log level<commit_after>#include <pylon_camera/pylon_camera_opencv_node.h>

using namespace std;

namespace pylon_camera
{

PylonCameraOpenCVNode::PylonCameraOpenCVNode() :
                    cv_img_rect_(),
                    cv_img_seq_(),
                    cv_img_hdr_(),
                    exp_times_(),
                    img_rect_pub_(nh_.advertise<sensor_msgs::Image>("image_rect", 10)),
                    img_seq_pub_(nh_.advertise<sensor_msgs::Image>("image_seq", 10)),
                    img_hdr_pub_(nh_.advertise<sensor_msgs::Image>("image_hdr", 10)),
                    exp_times_pub_(nh_.advertise<pylon_camera_msgs::SequenceExposureTimes>("seq_exp_times", 10)),
                    img_rectifier_(),
                    calib_loader_(),
                    img_raw_()
{
}

void PylonCameraOpenCVNode::getInitialCameraParameter()
{
    PylonCameraNode::getInitialCameraParameter();

    nh_.param<bool>("use_sequencer", params_.use_sequencer_, false);
    if (params_.use_sequencer_)
    {
        nh_.getParam("desired_seq_exp_times", params_.desired_seq_exp_times_);
        image_sequence_.resize(params_.desired_seq_exp_times_.size());
        //assert(params_.desired_seq_exp_times_.size() == 3);

        nh_.param<bool>("output_hdr_img", params_.output_hdr_, false);
    }

    nh_.param<std::string>("intrinsic_yaml_string",
                           params_.intrinsic_yaml_file_,
                           "INVALID_YAML_FILE");

    if (params_.intrinsic_yaml_file_ == "INVALID_YAML_FILE")
    {
        ROS_WARN("Yaml file string needed for rectification! Param: 'pylon_camera_node/intrinsic_yaml_string' has entry: %s",
                 params_.intrinsic_yaml_file_.c_str());
        ROS_WARN("Alternative: Get only distorted image by compiling 'WITHOUT_OPENCV'");
        ROS_INFO("Will only provide image_raw!");
        params_.have_intrinsic_data_ = false;
        if(params_.use_sequencer_){
            ROS_WARN("Sequencer-Mode needs intrinsic data! Will disable sequencer!");
            params_.use_sequencer_ =  false;
            params_.output_hdr_ = false;
        }
    }
}

uint32_t PylonCameraOpenCVNode::getNumSubscribers() const
{
    return img_raw_pub_.getNumSubscribers() + img_rect_pub_.getNumSubscribers()
         + img_seq_pub_.getNumSubscribers()
         + img_hdr_pub_.getNumSubscribers();
}

uint32_t PylonCameraOpenCVNode::getNumSubscribersRaw() const
{
    return img_raw_pub_.getNumSubscribers();
}

uint32_t PylonCameraOpenCVNode::getNumSubscribersRect() const
{
    return img_rect_pub_.getNumSubscribers();
}
uint32_t PylonCameraOpenCVNode::getNumSubscribersSeq() const
{
    return img_seq_pub_.getNumSubscribers();
}
uint32_t PylonCameraOpenCVNode::getNumSubscribersHdr() const
{
    return img_hdr_pub_.getNumSubscribers();
}
bool PylonCameraOpenCVNode::init()
{

    if (!PylonCameraNode::initAndRegister())
    {
        return false;
    }

    if (params_.use_sequencer_)
    {
        pylon_camera_->setupSequencer(params_.desired_seq_exp_times_);
    }

    if (!PylonCameraNode::startGrabbing())
    {
        return false;
    }

    cv_img_rect_.header = img_raw_msg_.header;
    cv_img_seq_.header = img_raw_msg_.header;
    cv_img_hdr_.header = img_raw_msg_.header;
    exp_times_.header = img_raw_msg_.header;
    // Encoding of pixels -- channel meaning, ordering, size
    // taken from the list of strings in include/sensor_msgs/image_encodings.h
    cv_img_rect_.encoding = pylon_camera_->imageEncoding();
    cv_img_seq_.encoding = sensor_msgs::image_encodings::BGR8;
    cv_img_hdr_.encoding = pylon_camera_->imageEncoding();

    cv_img_hdr_.image  = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC1);
    cv_img_seq_.image  = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC3);
    cv_img_rect_.image = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC1);

    if (params_.use_sequencer_)
    {
        for (std::size_t i = 0; i < params_.desired_seq_exp_times_.size(); ++i)
        {
            image_sequence_[i] = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC1);
            exp_times_.exp_times.data.push_back(params_.desired_seq_exp_times_[i]);
        }
    }

    calib_loader_.init(params_.intrinsic_yaml_file_);

    if (!calib_loader_.loadCalib())
    {
        params_.have_intrinsic_data_ = false;
        cerr << "Error reading intrinsic calibration from yaml file!" << endl;
    }
    if (calib_loader_.img_cols() != (int)img_raw_msg_.width || calib_loader_.img_rows()
                                                          != (int)img_raw_msg_.height)
    {
        cerr << "Error: Image size from yaml file (" << calib_loader_.img_cols() << ", "
             << calib_loader_.img_rows()
             << ") does not match to the size of the connected camera ("
             << img_raw_msg_.width
             << ", " << img_raw_msg_.height << ")! Will publish only raw image!" << endl;
        params_.have_intrinsic_data_ = false;
        if(params_.use_sequencer_){
            ROS_WARN("Sequencer-Mode needs intrinsic data! Will disable sequencer!");
            params_.use_sequencer_ =  false;
            params_.output_hdr_ = false;
        }
    }
    else
    {
        params_.have_intrinsic_data_ = true;
        setupCameraInfoMsg();
        img_rectifier_.setupRectifyingMap(calib_loader_.K(),
                                          calib_loader_.D(),
                                          pylon_camera_->imageCols(),
                                          pylon_camera_->imageRows());
    }

    return true;
}
void PylonCameraOpenCVNode::setupCameraInfoMsg()
{

    cam_info_msg_.distortion_model = "plumb_bob";
    cam_info_msg_.D.resize(5);

    for (uint i = 0; i < 5; ++i)
    {
        double d = calib_loader_.D().at<double>(0, i);
        cam_info_msg_.D[i] = d;
    }

    int pos = 0;
    for (uint i = 0; i < 3; ++i)
    {
        for (uint j = 0; j < 3; ++j)
        {
            cam_info_msg_.K[pos++] = calib_loader_.K().at<double>(i, j);
        }
    }

    pos = 0;
    for (uint i = 0; i < 3; ++i)
    {
        for (uint j = 0; j < 3; ++j)
        {
            cam_info_msg_.P[pos++] = calib_loader_.K().at<double>(i, j);
        }
        cam_info_msg_.P[pos++] = 0;
    }
    //	cam_info_msg_.P = 0.0;
    //	cam_info_msg_.R = 0.0;
    //	cam_info_msg_.binning_x =
    //	cam_info_msg_.binning_y =
    //	cam_info_msg_.roi =
}

bool PylonCameraOpenCVNode::grabImage()
{
    if (!PylonCameraNode::grabImage())
        return false;

    //img_raw_ = cv::Mat(pylon_camera_->img_rows(), pylon_camera_->img_cols(), CV_8UC1);

    //memcpy(img_raw_.ptr(), img_raw_msg_.data.data(), pylon_camera_->image_size());

    boost::lock_guard<boost::recursive_mutex> lock(grab_mutex_);
    img_raw_ = cv::Mat(pylon_camera_->imageRows(), pylon_camera_->imageCols(), CV_8UC1, img_raw_msg_.data.data());

    if (pylon_camera_->isOwnBrightnessFunctionRunning())
    {
//        int c = pylon_camera_->img_cols(), r = pylon_camera_->img_rows();
//        pylon_opencv_interface_.exp_search_params_.current_brightness_ = cv::mean(img_raw_.colRange(0.25 * c, 0.75 * c)
//                        .rowRange(0.25 * r,
//                                  0.75 * r))
//                                            .val[0];
        pylon_camera_->exp_search_params_.current_brightness_ = cv::mean(img_raw_).val[0];
//        .colRange(0.25 * c, 0.75 * c)
//                        .rowRange(0.25 * r,
//                                  0.75 * r))
//                                            .val[0];
    }

    if (params_.have_intrinsic_data_)
    {
        cv_img_rect_.header = img_raw_msg_.header;
        img_rectifier_.rectify(img_raw_, cv_img_rect_.image);
    }

    return true;
}
bool PylonCameraOpenCVNode::grabSequence()
{
    boost::lock_guard<boost::recursive_mutex> lock(grab_mutex_);
    image_sequence_.resize(params_.desired_seq_exp_times_.size());
    bool success = true;
    std::size_t mid = params_.desired_seq_exp_times_.size() / 2;
    for (std::size_t i = 0; i < params_.desired_seq_exp_times_.size(); ++i)
    {
        if (!(pylon_camera_->grab(image_sequence_[i])))
        {
            if (pylon_camera_->isCamRemoved())
            {
                ROS_ERROR("Pylon Camera has been removed!");
                ros::shutdown();
            }
            else
            {
                ROS_INFO("Pylon Interface returned NULL-Pointer!");
            }
            success = false;
        }
        if (i == mid && success)
        {
            if (getNumSubscribersRaw())
            {
                img_raw_msg_.data = std::vector<uint8_t>(image_sequence_[i].data,
                                                         image_sequence_[i].data + pylon_camera_->imageSize());
            }
            if (params_.have_intrinsic_data_)
            {
                if (getNumSubscribersRect())
                {
                    img_rectifier_.rectify(image_sequence_[i], cv_img_rect_.image);
                }
            }
        }
    }
    if (!success)
        return false;

    img_raw_msg_.header.stamp = ros::Time::now();
    cam_info_msg_.header.stamp = img_raw_msg_.header.stamp;
    cv_img_rect_.header = img_raw_msg_.header;
    cv_img_seq_.header.stamp = img_raw_msg_.header.stamp;
    exp_times_.header.stamp = img_raw_msg_.header.stamp;

    if (params_.output_hdr_)
    {
        if (getNumSubscribersHdr())
        {
            //ros::Time now = ros::Time::now();
            cv_img_hdr_.header.stamp = img_raw_msg_.header.stamp;
            if (!hdr_generator_.merge(image_sequence_, pylon_camera_->sequencerExposureTimes(), hdr_img_))
            {
                cerr << "Error while generating HDR image" << endl;
            }
            //ROS_INFO_STREAM("HDR TOOK " << (ros::Time::now() - now).toSec());
            img_rectifier_.rectify(hdr_img_, cv_img_hdr_.image);
        }
    }
    else
    {
        // I put this into the else clause of hdr as I don't think it makes sense to produce a psoido BGR image out of three grayscale images
        if (getNumSubscribersSeq() && image_sequence_.size() == 3)
        {
            cv::Mat img_seq_bgr;
            cv::merge(image_sequence_.data(), 3, img_seq_bgr);

            img_rectifier_.rectify(img_seq_bgr, cv_img_seq_.image);
        }
    }

    return true;
}

PylonCameraOpenCVNode::~PylonCameraOpenCVNode()
{
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: OSubComponent.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: fs $ $Date: 2000-11-08 15:35:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_OSUBCOMPONENT_HXX_
#define _CONNECTIVITY_OSUBCOMPONENT_HXX_

#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/Weak.hxx>
#endif

namespace connectivity
{

    //************************************************************
    // OSubComponent
    //************************************************************
    template <class T > class OSubComponent
    {
    protected:
        // the parent must support the tunnel implementation
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > m_xParent;
        T*  m_pDerivedImplementation;

    public:
        OSubComponent(
                const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xParent,
                T* _pDerivedImplementation)
            :m_xParent(_xParent)
            ,m_pDerivedImplementation(_pDerivedImplementation)
        {
        }

    protected:
        void dispose_ChildImpl()
        {
            ::osl::MutexGuard aGuard( m_pDerivedImplementation->rBHelper.rMutex );
            m_xParent = NULL;
        }
        void relase_ChildImpl()
        {
            if (osl_decrementInterlockedCount( &m_pDerivedImplementation->m_refCount ) == 0)
            {
                if (!m_pDerivedImplementation->rBHelper.bDisposed && !m_pDerivedImplementation->rBHelper.bInDispose)
                {
                    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xHoldAlive( *m_pDerivedImplementation );

                    // remember the parent
                    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xParent;
                    {
                        ::osl::MutexGuard aGuard( m_pDerivedImplementation->rBHelper.rMutex );
                        xParent = m_xParent;
                        m_xParent = NULL;
                    }

                    // First dispose
                    m_pDerivedImplementation->dispose();

                    // only the alive ref holds the object
                    OSL_ASSERT( m_pDerivedImplementation->m_refCount == 1 );

                    // release the parent in the ~
                    if (xParent.is())
                    {
                        ::osl::MutexGuard aGuard( m_pDerivedImplementation->rBHelper.rMutex );
                        m_xParent = xParent;
                    }

                    // destroy the object if xHoldAlive decrement the refcount to 0
                    return;
                }
            }
        }
    };
}
#endif // _CONNECTIVITY_OSUBCOMPONENT_HXX_

<commit_msg>release_child: delete m_pDerivedImplementation if the ref count goes to 0<commit_after>/*************************************************************************
 *
 *  $RCSfile: OSubComponent.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: fs $ $Date: 2001-04-12 09:44:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_OSUBCOMPONENT_HXX_
#define _CONNECTIVITY_OSUBCOMPONENT_HXX_

#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/Weak.hxx>
#endif

namespace connectivity
{

    //************************************************************
    // OSubComponent
    //************************************************************
    template <class T > class OSubComponent
    {
    protected:
        // the parent must support the tunnel implementation
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > m_xParent;
        T*  m_pDerivedImplementation;

    public:
        OSubComponent(
                const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xParent,
                T* _pDerivedImplementation)
            :m_xParent(_xParent)
            ,m_pDerivedImplementation(_pDerivedImplementation)
        {
        }

    protected:
        void dispose_ChildImpl()
        {
            ::osl::MutexGuard aGuard( m_pDerivedImplementation->rBHelper.rMutex );
            m_xParent = NULL;
        }
        void relase_ChildImpl()
        {
            if (osl_decrementInterlockedCount( &m_pDerivedImplementation->m_refCount ) == 0)
            {
                if (!m_pDerivedImplementation->rBHelper.bDisposed && !m_pDerivedImplementation->rBHelper.bInDispose)
                {
                    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xHoldAlive( *m_pDerivedImplementation );

                    // remember the parent
                    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xParent;
                    {
                        ::osl::MutexGuard aGuard( m_pDerivedImplementation->rBHelper.rMutex );
                        xParent = m_xParent;
                        m_xParent = NULL;
                    }

                    // First dispose
                    m_pDerivedImplementation->dispose();

                    // only the alive ref holds the object
                    OSL_ASSERT( m_pDerivedImplementation->m_refCount == 1 );

                    // release the parent in the ~
                    if (xParent.is())
                    {
                        ::osl::MutexGuard aGuard( m_pDerivedImplementation->rBHelper.rMutex );
                        m_xParent = xParent;
                    }

                    // destroy the object if xHoldAlive decrement the refcount to 0
                    return;
                }
                else
                    delete m_pDerivedImplementation;
            }
        }
    };
}
#endif // _CONNECTIVITY_OSUBCOMPONENT_HXX_

<|endoftext|>


<commit_before>
#include <limits.h>

#include <ELModule.h>
#include <ELAssert.h>
#include <ELInternet.h>
#include <ELUtilities.h>
#include <ELInternetDevice_ESP8266.h>

class CModule_ESP8266 : public CModule, public IInternetDevice
{
public:

	CModule_ESP8266(
		)
		:
		CModule("8266", 0, 0, NULL, 1000, 2, false)
	{
	}

	virtual void
	Setup(
		void)
	{
		MReturnOnError(serialPort == NULL);
		serialPort->begin(115200);

		if(rstPin != 0xFF)
		{
			pinMode(rstPin, OUTPUT);
			digitalWriteFast(rstPin, 1);
		}
		if(chPDPin != 0xFF)
		{
			pinMode(chPDPin, OUTPUT);
			digitalWriteFast(chPDPin, 1);
		}
		if(gpio0Pin != 0xFF)
		{
			pinMode(gpio0Pin, OUTPUT);
			digitalWriteFast(gpio0Pin, 1);
		}
		if(gpio2Pin != 0xFF)
		{
			pinMode(gpio2Pin, OUTPUT);
			digitalWriteFast(gpio2Pin, 1);
		}

		while(ready == false)
		{
			Update(0);
		}

		IssueCommand("ATE0", 5000);
		WaitCommandCompleted();

		IssueCommand("AT+CWMODE=3", 5000);
		WaitCommandCompleted();
	}

	virtual void
	Update(
		uint32_t	inDeltaTimeUS)
	{
		size_t	bytesAvailable = serialPort->available();
		char	tmpBuffer[256];

		if(bytesAvailable == 0)
		{
			return;
		}

		bytesAvailable = MMin(bytesAvailable, sizeof(tmpBuffer));
		serialPort->readBytes(tmpBuffer, bytesAvailable);

		for(size_t i = 0; i < bytesAvailable; ++i)
		{
			char c = tmpBuffer[i];

			SIPDBuffer*	targetIPDBuffer = ipdBuffer + ipdIndex;
			if(targetIPDBuffer->totalBytes > 0)
			{
				targetIPDBuffer->buffer[targetIPDBuffer->bufferIndex++] = c;
				if(targetIPDBuffer->bufferIndex >= targetIPDBuffer->totalBytes)
				{
					// we have all the ipd data now
					ipdIndex = !ipdIndex;
					ipdBuffer[ipdIndex].bufferIndex = 0;
					ipdBuffer[ipdIndex].totalBytes = 0;

					commandResultLength = 0;
				}
				continue;
			}

			if(ipdParsing)
			{
				if(c == ':')
				{
					commandResultBuffer[commandResultLength++] = 0;
					int	channel, intPDBBytes;
					sscanf(commandResultBuffer, "%d,%d", &channel, &intPDBBytes);

					ipdBuffer[ipdIndex].bufferIndex = 0;
					ipdBuffer[ipdIndex].totalBytes = (size_t)intPDBBytes;
					ipdBuffer[ipdIndex].channel = channel;

					ipdParsing = false;
					commandResultLength = 0;
				}
				else
				{
					commandResultBuffer[commandResultLength++] = c;
				}

				continue;
			}

			if(c == '\n' || c == '\r')
			{
				if(commandResultLength > 0)
				{
					commandResultBuffer[commandResultLength] = 0;
					commandResultLength = 0;

					ProcessInputResponse(commandResultBuffer);
				}
			}
			else
			{
				if(commandResultLength < sizeof(commandResultBuffer) - 1)
				{
					commandResultBuffer[commandResultLength++] = c;

					if(commandResultLength == 5 && strncmp(commandResultBuffer, "+IPD,", 5) == 0)
					{
						ipdParsing = true;
						commandResultLength = 0;
					}
				}
			}
		}
	}

	void
	ProcessInputResponse(
		char*	inCmd)
	{
		//DebugMsgLocal(eDbgLevel_Always, "Response: %s", inCmd);

		if(strcmp(inCmd, "OK") == 0 || strcmp(inCmd, "SEND OK") == 0)
		{
			commandSucceeded = true;
			commandPending = false;
		}
		else if(strcmp(inCmd, "ERROR") == 0)
		{
			commandSucceeded = false;
			commandPending = false;
		}
		else if(strcmp(inCmd, "ready") == 0)
		{
			ready = true;
		}
	}

	virtual void
	ConnectToAP(
		char const*		inSSID,
		char const*		inPassword,
		EWirelessPWEnc	inPasswordEncryption)
	{
		IssueCommand("AT+CWJAP=\"%s\",\"%s\"", 15000, inSSID, inPassword);
		WaitCommandCompleted();
	}

	virtual void
	SetIPAddr(
		uint32_t	inIPAddr,
		uint32_t	inSubnetAddr,
		uint32_t	inGatewayAddr)
	{
		IssueCommand("AT+CIPSTA_CUR=\"%d.%d.%d.%d\",\"%d.%d.%d.%d\",\"%d.%d.%d.%d\"", 15000,
			(inIPAddr >> 24) & 0xFF,
			(inIPAddr >> 16) & 0xFF,
			(inIPAddr >> 8) & 0xFF,
			(inIPAddr >> 0) & 0xFF,
			(inGatewayAddr >> 24) & 0xFF,
			(inGatewayAddr >> 16) & 0xFF,
			(inGatewayAddr >> 8) & 0xFF,
			(inGatewayAddr >> 0) & 0xFF,
			(inSubnetAddr >> 24) & 0xFF,
			(inSubnetAddr >> 16) & 0xFF,
			(inSubnetAddr >> 8) & 0xFF,
			(inSubnetAddr >> 0) & 0xFF
			);
		WaitCommandCompleted();
	}

	virtual bool
	Server_Open(
		uint16_t	inServerPort)
	{
		IssueCommand("AT+CIPMUX=1", 5000);
		WaitCommandCompleted();
		IssueCommand("AT+CIPSERVER=1,%d", 10000, inServerPort);
		WaitCommandCompleted();
		return true;
	}

	virtual void
	Server_Close(
		uint16_t	inServerPort)
	{

	}

	virtual void
	Server_GetData(
		uint16_t	inServerPort,
		uint16_t&	outTransactionPort,
		size_t&		ioBufferSize,
		char*		outBuffer)
	{
		SIPDBuffer*	targetIPDBuffer = ipdBuffer + !ipdIndex;

		if(targetIPDBuffer->totalBytes > 0 && targetIPDBuffer->totalBytes == targetIPDBuffer->bufferIndex)
		{
			ioBufferSize = MMin(ioBufferSize, targetIPDBuffer->totalBytes);
			memcpy(outBuffer, targetIPDBuffer->buffer, ioBufferSize);
			outTransactionPort = targetIPDBuffer->channel;
			targetIPDBuffer->totalBytes = 0;
			targetIPDBuffer->bufferIndex = 0;
		}
		else
		{
			ioBufferSize = 0;
		}
	}

	virtual void
	Server_SendData(
		uint16_t	inServerPort,
		uint16_t	inTransactionPort,
		size_t		inBufferSize,
		char const*	inBuffer)
	{
		IssueCommand("AT+CIPSEND=%d,%d", 5000, inTransactionPort, inBufferSize);
		while(serialPort->available() == 0 || serialPort->read() != '>')
		{
			delay(1);
		}
		serialPort->write((uint8_t*)inBuffer, inBufferSize);
		WaitCommandCompleted();
	}

	virtual void
	Server_CloseConnection(
		uint16_t	inServerPort,
		uint16_t	inTransactionPort)
	{
		IssueCommand("AT+CIPCLOSE=%d", 5000, inTransactionPort);
		WaitCommandCompleted();
	}

	virtual bool
	Connection_Open(
		uint16_t&	outLocalPort,
		uint16_t	inRemoteServerPort,
		char const*	inRemoteServerAddress)
	{
		return false;
	}

	virtual void
	Connection_Close(
		uint16_t	inLocalPort)
	{

	}

	virtual void
	Connection_InitiateRequest(
		uint16_t	inLocalPort,
		size_t		inDataSize,
		char const*	inData)
	{

	}

	virtual void
	Connection_GetData(
		uint16_t	inPort,
		size_t&		ioBufferSize,
		char*		outBuffer)
	{

	}

	void
	Configure(
		HardwareSerial*	inSerialPort,
		uint8_t	inRstPin,
		uint8_t	inChPDPin,
		uint8_t	inGPIO0,
		uint8_t	inGPIO2)
	{
		serialPort = inSerialPort;
		rstPin = inRstPin;
		chPDPin = inChPDPin;
		gpio0Pin = inGPIO0;
		gpio2Pin = inGPIO2;
	}

	void
	IssueCommand(
		char const*	inCommand,
		uint32_t	inTimeoutMS,
		...)
	{
		char vabuffer[256];
		va_list	varArgs;

		va_start(varArgs, inTimeoutMS);
		vsnprintf(vabuffer, sizeof(vabuffer) - 1, inCommand, varArgs);
		vabuffer[sizeof(vabuffer) - 1] = 0;	// Ensure a valid string
		va_end(varArgs);

		//DebugMsgLocal(eDbgLevel_Always, "Command: %s\n", vabuffer);
		serialPort->write(vabuffer);
		serialPort->write("\r\n");
		commandPending = true;
		commandTimeoutMS = millis() + inTimeoutMS;
	}

	void
	WaitCommandCompleted(
		void)
	{
		while(commandPending && millis() < commandTimeoutMS)
		{
			Update(0);
		}

		if(commandPending)
		{
			commandPending = false;
			commandSucceeded = false;
			commandResultBuffer[0] = 0;
		}
	}

	struct SIPDBuffer
	{
		char	buffer[1024];
		int		channel;
		size_t	bufferIndex;
		size_t	totalBytes;
	};

	HardwareSerial*	serialPort;
	uint8_t	rstPin;
	uint8_t	chPDPin;
	uint8_t	gpio0Pin;
	uint8_t	gpio2Pin;

	int			ipdIndex;
	SIPDBuffer	ipdBuffer[2];
	bool		ipdParsing;

	bool		ready;

	bool		commandPending;
	bool		commandSucceeded;
	uint64_t	commandTimeoutMS;
	size_t		commandResultLength;
	char		commandResultBuffer[256];

	static CModule_ESP8266	module;
};
CModule_ESP8266	CModule_ESP8266::module;

IInternetDevice*
GetInternetDevice_ESP8266(
	HardwareSerial*	inSerialPort,
	uint8_t	inRstPin,
	uint8_t	inChPDPin,
	uint8_t	inGPIO0,
	uint8_t	inGPIO2)
{
	CModule_ESP8266::module.Configure(inSerialPort, inRstPin, inChPDPin, inGPIO0, inGPIO2);
	CModule_ESP8266::module.SetEnabledState(true);
	return &CModule_ESP8266::module;
}
<commit_msg>Fix an device initialization bug that was accidentally masked during initial testing, buffer output<commit_after>
#include <limits.h>

#include <ELModule.h>
#include <ELAssert.h>
#include <ELInternet.h>
#include <ELUtilities.h>
#include <ELInternetDevice_ESP8266.h>

class CModule_ESP8266 : public CModule, public IInternetDevice
{
public:

	CModule_ESP8266(
		)
		:
		CModule("8266", 0, 0, NULL, 1000, 2, false)
	{
	}

	virtual void
	Setup(
		void)
	{
		MReturnOnError(serialPort == NULL);
		serialPort->begin(115200);

		if(rstPin != 0xFF)
		{
			pinMode(rstPin, OUTPUT);
			delay(10);	// This is a bit of a mystery but 4 hours of experimentation says that the device will not work without this delay right exactly here
			digitalWriteFast(rstPin, 1);
		}

		if(chPDPin != 0xFF)
		{
			pinMode(chPDPin, OUTPUT);
			digitalWriteFast(chPDPin, 1);
		}

		if(gpio0Pin != 0xFF)
		{
			pinMode(gpio0Pin, OUTPUT);
			digitalWriteFast(gpio0Pin, 1);
		}
		if(gpio2Pin != 0xFF)
		{
			pinMode(gpio2Pin, OUTPUT);
			digitalWriteFast(gpio2Pin, 1);
		}

		while(ready == false)
		{
			Update(0);
		}

		IssueCommand("ATE0", 5000);
		WaitCommandCompleted();

		IssueCommand("AT+CWMODE=3", 5000);
		WaitCommandCompleted();
	}

	virtual void
	Update(
		uint32_t	inDeltaTimeUS)
	{
		size_t	bytesAvailable = serialPort->available();
		char	tmpBuffer[256];

		if(bytesAvailable == 0)
		{
			return;
		}

		bytesAvailable = MMin(bytesAvailable, sizeof(tmpBuffer));
		serialPort->readBytes(tmpBuffer, bytesAvailable);

		for(size_t i = 0; i < bytesAvailable; ++i)
		{
			char c = tmpBuffer[i];

			SIPDBuffer*	targetIPDBuffer = ipdBuffer + ipdIndex;
			if(targetIPDBuffer->totalBytes > 0)
			{
				targetIPDBuffer->buffer[targetIPDBuffer->bufferIndex++] = c;
				if(targetIPDBuffer->bufferIndex >= targetIPDBuffer->totalBytes)
				{
					// we have all the ipd data now
					ipdIndex = !ipdIndex;
					ipdBuffer[ipdIndex].bufferIndex = 0;
					ipdBuffer[ipdIndex].totalBytes = 0;

					commandResultLength = 0;
				}
				continue;
			}

			if(ipdParsing)
			{
				if(c == ':')
				{
					commandResultBuffer[commandResultLength++] = 0;
					int	channel, intPDBBytes;
					sscanf(commandResultBuffer, "%d,%d", &channel, &intPDBBytes);

					ipdBuffer[ipdIndex].bufferIndex = 0;
					ipdBuffer[ipdIndex].totalBytes = (size_t)intPDBBytes;
					ipdBuffer[ipdIndex].channel = channel;

					ipdParsing = false;
					commandResultLength = 0;
				}
				else
				{
					commandResultBuffer[commandResultLength++] = c;
				}

				continue;
			}

			if(c == '\n' || c == '\r')
			{
				if(commandResultLength > 0)
				{
					commandResultBuffer[commandResultLength] = 0;
					commandResultLength = 0;

					ProcessInputResponse(commandResultBuffer);
				}
			}
			else
			{
				if(commandResultLength < sizeof(commandResultBuffer) - 1)
				{
					commandResultBuffer[commandResultLength++] = c;

					if(commandResultLength == 5 && strncmp(commandResultBuffer, "+IPD,", 5) == 0)
					{
						ipdParsing = true;
						commandResultLength = 0;
					}
				}
			}
		}
	}

	void
	ProcessInputResponse(
		char*	inCmd)
	{
		//DebugMsgLocal(eDbgLevel_Always, "Response: %s", inCmd);

		if(strcmp(inCmd, "OK") == 0 || strcmp(inCmd, "SEND OK") == 0)
		{
			commandSucceeded = true;
			commandPending = false;
		}
		else if(strcmp(inCmd, "ERROR") == 0)
		{
			commandSucceeded = false;
			commandPending = false;
		}
		else if(strcmp(inCmd, "ready") == 0)
		{
			ready = true;
		}
	}

	virtual void
	ConnectToAP(
		char const*		inSSID,
		char const*		inPassword,
		EWirelessPWEnc	inPasswordEncryption)
	{
		IssueCommand("AT+CWJAP=\"%s\",\"%s\"", 15000, inSSID, inPassword);
		WaitCommandCompleted();
	}

	virtual void
	SetIPAddr(
		uint32_t	inIPAddr,
		uint32_t	inSubnetAddr,
		uint32_t	inGatewayAddr)
	{
		IssueCommand("AT+CIPSTA_CUR=\"%d.%d.%d.%d\",\"%d.%d.%d.%d\",\"%d.%d.%d.%d\"", 15000,
			(inIPAddr >> 24) & 0xFF,
			(inIPAddr >> 16) & 0xFF,
			(inIPAddr >> 8) & 0xFF,
			(inIPAddr >> 0) & 0xFF,
			(inGatewayAddr >> 24) & 0xFF,
			(inGatewayAddr >> 16) & 0xFF,
			(inGatewayAddr >> 8) & 0xFF,
			(inGatewayAddr >> 0) & 0xFF,
			(inSubnetAddr >> 24) & 0xFF,
			(inSubnetAddr >> 16) & 0xFF,
			(inSubnetAddr >> 8) & 0xFF,
			(inSubnetAddr >> 0) & 0xFF
			);
		WaitCommandCompleted();
	}

	virtual bool
	Server_Open(
		uint16_t	inServerPort)
	{
		IssueCommand("AT+CIPMUX=1", 5000);
		WaitCommandCompleted();
		IssueCommand("AT+CIPSERVER=1,%d", 10000, inServerPort);
		WaitCommandCompleted();
		return true;
	}

	virtual void
	Server_Close(
		uint16_t	inServerPort)
	{

	}

	virtual void
	Server_GetData(
		uint16_t	inServerPort,
		uint16_t&	outTransactionPort,
		size_t&		ioBufferSize,
		char*		outBuffer)
	{
		SIPDBuffer*	targetIPDBuffer = ipdBuffer + !ipdIndex;

		if(targetIPDBuffer->totalBytes > 0 && targetIPDBuffer->totalBytes == targetIPDBuffer->bufferIndex)
		{
			ioBufferSize = MMin(ioBufferSize, targetIPDBuffer->totalBytes);
			memcpy(outBuffer, targetIPDBuffer->buffer, ioBufferSize);
			outTransactionPort = targetIPDBuffer->channel;
			targetIPDBuffer->totalBytes = 0;
			targetIPDBuffer->bufferIndex = 0;
		}
		else
		{
			ioBufferSize = 0;
		}
	}

	virtual void
	Server_SendData(
		uint16_t	inServerPort,
		uint16_t	inTransactionPort,
		size_t		inBufferSize,
		char const*	inBuffer)
	{
		SSendBuffer*	targetBuffer = channelSendBuffers + inTransactionPort;

		while(inBufferSize > 0)
		{
			int	bytesToCopy = MMin(inBufferSize, sizeof(targetBuffer->sendBuffer) - targetBuffer->sendBufferLength);
			memcpy(targetBuffer->sendBuffer + targetBuffer->sendBufferLength, inBuffer, bytesToCopy);
			targetBuffer->sendBufferLength += bytesToCopy;
			if(targetBuffer->sendBufferLength >= (int)sizeof(targetBuffer->sendBuffer))
			{
				TransmitPendingData(inTransactionPort);
			}
			inBufferSize -= bytesToCopy;
			inBuffer += bytesToCopy;
		}

	}

	virtual void
	Server_CloseConnection(
		uint16_t	inServerPort,
		uint16_t	inTransactionPort)
	{
		TransmitPendingData(inTransactionPort);
		IssueCommand("AT+CIPCLOSE=%d", 5000, inTransactionPort);
		WaitCommandCompleted();
	}

	void
	TransmitPendingData(
		uint16_t	inTransactionPort)
	{
		SSendBuffer*	targetBuffer = channelSendBuffers + inTransactionPort;
		if(targetBuffer->sendBufferLength == 0)
		{
			return;
		}

		IssueCommand("AT+CIPSEND=%d,%d", 5000, inTransactionPort, targetBuffer->sendBufferLength);
		while(serialPort->available() == 0 || serialPort->read() != '>')
		{
			delay(1);
		}
		serialPort->write((uint8_t*)targetBuffer->sendBuffer, targetBuffer->sendBufferLength);
		WaitCommandCompleted();
		targetBuffer->sendBufferLength = 0;
	}

	virtual bool
	Connection_Open(
		uint16_t&	outLocalPort,
		uint16_t	inRemoteServerPort,
		char const*	inRemoteServerAddress)
	{
		return false;
	}

	virtual void
	Connection_Close(
		uint16_t	inLocalPort)
	{

	}

	virtual void
	Connection_InitiateRequest(
		uint16_t	inLocalPort,
		size_t		inDataSize,
		char const*	inData)
	{

	}

	virtual void
	Connection_GetData(
		uint16_t	inPort,
		size_t&		ioBufferSize,
		char*		outBuffer)
	{

	}

	void
	Configure(
		HardwareSerial*	inSerialPort,
		uint8_t	inRstPin,
		uint8_t	inChPDPin,
		uint8_t	inGPIO0,
		uint8_t	inGPIO2)
	{
		serialPort = inSerialPort;
		rstPin = inRstPin;
		chPDPin = inChPDPin;
		gpio0Pin = inGPIO0;
		gpio2Pin = inGPIO2;
	}

	void
	IssueCommand(
		char const*	inCommand,
		uint32_t	inTimeoutMS,
		...)
	{
		char vabuffer[256];
		va_list	varArgs;

		va_start(varArgs, inTimeoutMS);
		vsnprintf(vabuffer, sizeof(vabuffer) - 1, inCommand, varArgs);
		vabuffer[sizeof(vabuffer) - 1] = 0;	// Ensure a valid string
		va_end(varArgs);

		//DebugMsgLocal(eDbgLevel_Always, "Command: %s\n", vabuffer);
		serialPort->write(vabuffer);
		serialPort->write("\r\n");
		commandPending = true;
		commandTimeoutMS = millis() + inTimeoutMS;
	}

	void
	WaitCommandCompleted(
		void)
	{
		while(commandPending && millis() < commandTimeoutMS)
		{
			Update(0);
		}

		if(commandPending)
		{
			commandPending = false;
			commandSucceeded = false;
			commandResultBuffer[0] = 0;
		}
	}

	struct SIPDBuffer
	{
		char	buffer[1024];
		int		channel;
		size_t	bufferIndex;
		size_t	totalBytes;
	};

	struct SSendBuffer
	{
		int		sendBufferLength;
		char	sendBuffer[512];
	};

	HardwareSerial*	serialPort;
	uint8_t	rstPin;
	uint8_t	chPDPin;
	uint8_t	gpio0Pin;
	uint8_t	gpio2Pin;

	int			ipdIndex;
	SIPDBuffer	ipdBuffer[2];
	bool		ipdParsing;

	bool		ready;

	bool		commandPending;
	bool		commandSucceeded;
	uint64_t	commandTimeoutMS;
	size_t		commandResultLength;
	char		commandResultBuffer[256];

	SSendBuffer	channelSendBuffers[4];

	static CModule_ESP8266	module;
};
CModule_ESP8266	CModule_ESP8266::module;

IInternetDevice*
GetInternetDevice_ESP8266(
	HardwareSerial*	inSerialPort,
	uint8_t	inRstPin,
	uint8_t	inChPDPin,
	uint8_t	inGPIO0,
	uint8_t	inGPIO2)
{
	CModule_ESP8266::module.Configure(inSerialPort, inRstPin, inChPDPin, inGPIO0, inGPIO2);
	CModule_ESP8266::module.SetEnabledState(true);
	return &CModule_ESP8266::module;
}
<|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <stdlib.h>
#include "DINAP.h"

#define MINUTE 60 //60 seconds per minute

using namespace std;

int main(int argc, char *argv[])
{
  pid_t pid, sid;
  pid = fork();         //Fork the parent process

  if (pid < 0)
    exit(EXIT_FAILURE); //Fork has failed - exit with error

  if (pid > 0)
    exit(EXIT_SUCCESS); //Fork worked - close the parent process

  umask(0);             //Change the file mask

  //Setup Logging
  openlog("dinapd", LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_DAEMON);

  //Create a new signature id for our child
  sid = setsid();
  if (sid < 0)
  {
    syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to create SID");
    exit(EXIT_FAILURE);
  }

  //Drop superuser privileges in correct order
  if (setgid(getgid()) == -1)
  {
    syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to set group id");
    exit(EXIT_FAILURE);
  }

  if (setuid(getuid()) == -1)
  {
    syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to set user id");
    exit(EXIT_FAILURE);
  }

  //Change to common working directory
  if ((chdir("/")) < 0)
  {
    syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to change working directory");
    exit(EXIT_FAILURE);
  }

  //Close Standard File Descriptors
  close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO);

  //Create a DINAP object
  DINAP userSpecs = DINAP(STATE_NSW, 18, 25);   //TODO: Read these specs from command line arguments

  //Execute the main process
  while(true)
  {
    userSpecs.CheckWeatherInfo();   //Execute the process
    sleep((MINUTE * 1));            //Execute it every 1 minute (debug purposes)- TODO: Change to hourly rate
  }

  closelog();               //Close the log
  return(EXIT_SUCCESS);
}
<commit_msg>Main: - Using command line arguments to initialise the dinap module<commit_after>#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <stdlib.h>
#include "DINAP.h"
#include "types.h"

#define MINUTE 60 //60 seconds per minute

const state_collection_t statesOfAus[] = {
  {"NSW", STATE_NSW },
  {"VIC", STATE_VIC },
  {"QLD", STATE_QLD },
  {"WA",  STATE_WA  },
  {"SA",  STATE_SA  },
  {"TAS", STATE_TAS },
  {"ACT", STATE_ACT },
  {"NT",  STATE_NT  }
};

/*! @brief Verifies and parses the command line arguments sent to the daemon.
 *
 *  @param argc     - Number of arguments that daemon was called with.
 *  @param argv     - Argument vectors.
 *  @param stateID  - A pointer to a stateID, set via user config.
 *  @param pTemp    - A pointer to optimal user parker temp, set via user config.
 *  @param sTemp    - A pointer to optimal user shorts temp, set via user config.
 *
 *  @return - True if all arguments were parsed correctly.
 */
bool verifyArguments(int argc, char *argv[], TSTATE * const stateID, int * const pTemp, int * const sTemp)
{
  int i;
  bool rc = false;
  int bufferSize = 5;

  if (argc == 4)
  {
    /* Loop through the states of australia and
     * attempt to get a match between the known
     * states and what is in the config file.
     */
    for(i = 0; i < sizeof(statesOfAus) / sizeof(state_collection_t); i++)
    {
      if (strncmp(statesOfAus[i].stateName, argv[1], bufferSize) == 0)
      {
        syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_INFO), "Setting Location to: %s", argv[1]);
        *stateID = statesOfAus[i].stateID;
        rc = true;
        break;
      }
    }

    //Attempt to convert the specified temps in the config file from string to int.
    try {
      *pTemp = std::stoi(argv[2], nullptr, 10); //Convert to decimal integer
    } catch(const std::exception& e) {
      syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to parse parker temp: %s.", argv[2]);
      rc &= false;
    }

    try {
      *sTemp = std::stoi(argv[3], nullptr, 10); //Convert to decimal integer
    } catch(const std::exception& e) {
      syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to parse shorts temp: %s.", argv[3]);
      rc &= false;
    }
  }

  return rc;
}

int main(int argc, char *argv[])
{
  TSTATE stateID;
  int parker_temp, shorts_temp;
  pid_t pid, sid;
  pid = fork();         //Fork the parent process

  if (pid < 0)
    exit(EXIT_FAILURE); //Fork has failed - exit with error

  if (pid > 0)
    exit(EXIT_SUCCESS); //Fork worked - close the parent process

  umask(0);             //Change the file mask

  //Setup Logging
  openlog("dinapd", LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_DAEMON);

  //Create a new signature id for our child
  sid = setsid();
  if (sid < 0)
  {
    syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to create SID");
    exit(EXIT_FAILURE);
  }

  //Drop superuser privileges in correct order
  if (setgid(getgid()) == -1)
  {
    syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to set group id");
    exit(EXIT_FAILURE);
  }

  if (setuid(getuid()) == -1)
  {
    syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to set user id");
    exit(EXIT_FAILURE);
  }

  //Change to common working directory
  if ((chdir("/")) < 0)
  {
    syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to change working directory");
    exit(EXIT_FAILURE);
  }

  //Close Standard File Descriptors
  close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO);

  //Validate command line arguments
  if(verifyArguments(argc, argv, &stateID, &parker_temp, &shorts_temp))
  {
    //Create a DINAP object
    DINAP userSpecs = DINAP(stateID, parker_temp, shorts_temp);

    //Execute the main process
    while(true)
    {
      userSpecs.CheckWeatherInfo();   //Execute the process
      sleep((MINUTE * 60));           //Execute it every hour
    }
  }
  else
  {
    syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Unable to verify DINAPD config. Terminating.");
    exit(EXIT_FAILURE);
  }

  closelog();               //Close the log
  return(EXIT_SUCCESS);
}
<|endoftext|>


<commit_before><commit_msg>tweak<commit_after><|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "cvtest.h"
#include "opencv2/core/core.hpp"

using namespace std;
using namespace cv;

const string FEATURES2D_DIR = "features2d";
const string DETECTOR_DIR = FEATURES2D_DIR + "/feature_detectors";
const string DESCRIPTOR_DIR = FEATURES2D_DIR + "/descriptor_extractors";
const string IMAGE_FILENAME = "tsukuba.png";

/****************************************************************************************\
*            Regression tests for feature detectors comparing keypoints.                 *
\****************************************************************************************/

class CV_FeatureDetectorTest : public CvTest
{
public:
    CV_FeatureDetectorTest( const char* testName, const Ptr<FeatureDetector>& _fdetector ) :
        CvTest( testName, "cv::FeatureDetector::detect"), fdetector(_fdetector) {}

protected:
    virtual void run( int start_from )
    {
        const float maxPtDif = 1.f;
        const float maxSizeDif = 1.f;
        const float maxAngleDif = 2.f;
        const float maxResponseDif = 0.1f;

        string imgFilename = string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME;
        string resFilename = string(ts->get_data_path()) + DETECTOR_DIR + "/" + string(name) + "_res.xml.gz";

        if( fdetector.empty() )
        {
            ts->printf( CvTS::LOG, "Feature detector is empty" );
            ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
            return;
        }

        Mat image = imread( imgFilename, 0 );
        if( image.empty() )
        {
            ts->printf( CvTS::LOG, "image %s can not be read \n", imgFilename.c_str() );
            ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
            return;
        }

        FileStorage fs( resFilename, FileStorage::READ );

        vector<KeyPoint> calcKeypoints;
        fdetector->detect( image, calcKeypoints );

        if( fs.isOpened() ) // compare computed and valid keypoints
        {
            // TODO compare saved feature detector params with current ones
            vector<KeyPoint> validKeypoints;
            read( fs["keypoints"], validKeypoints );
            if( validKeypoints.empty() )
            {
                ts->printf( CvTS::LOG, "Keypoints can nod be read\n" );
                ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
                return;
            }

            int progress = 0, progressCount = validKeypoints.size() * calcKeypoints.size();
            int badPointCount = 0, commonPointCount = max(validKeypoints.size(), calcKeypoints.size());
            for( size_t v = 0; v < validKeypoints.size(); v++ )
            {
                int nearestIdx = -1;
                float minDist = std::numeric_limits<float>::max();

                for( size_t c = 0; c < calcKeypoints.size(); c++ )
                {
                    progress = update_progress( progress, v*calcKeypoints.size() + c, progressCount, 0 );
                    float curDist = norm( calcKeypoints[c].pt - validKeypoints[v].pt );
                    if( curDist < minDist )
                    {
                        minDist = curDist;
                        nearestIdx = c;
                    }
                }

                if( minDist > maxPtDif ||
                    fabs(calcKeypoints[nearestIdx].size - validKeypoints[v].size) > maxSizeDif ||
                    abs(calcKeypoints[nearestIdx].angle - validKeypoints[v].angle) > maxAngleDif ||
                    abs(calcKeypoints[nearestIdx].response - validKeypoints[v].response) > maxResponseDif ||
                    calcKeypoints[nearestIdx].octave != validKeypoints[v].octave

                    // TODO !!!!!!!
                    /*||
                    calcKeypoints[nearestIdx].class_id != validKeypoints[v].class_id*/ )
                {
                    badPointCount++;
                }
            }
            ts->printf( CvTS::LOG, "badPointCount = %d; validPointCount = %d; calcPointCount = %d\n",
                        badPointCount, validKeypoints.size(), calcKeypoints.size() );
            if( badPointCount > 0.9 * commonPointCount )
            {
                ts->printf( CvTS::LOG, "Bad accuracy!\n" );
                ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
                return;
            }
        }
        else // write
        {
            fs.open( resFilename, FileStorage::WRITE );
            if( !fs.isOpened() )
            {
                ts->printf( CvTS::LOG, "file %s can not be opened to write\n", resFilename.c_str() );
                ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
                return;
            }
            else
            {
                fs << "detector_params" << "{";
                fdetector->write( fs );
                fs << "}";

                write( fs, "keypoints", calcKeypoints );
            }
        }
        ts->set_failed_test_info( CvTS::OK );
    }

    Ptr<FeatureDetector> fdetector;
};

CV_FeatureDetectorTest fastTest( "detector_fast", createFeatureDetector("FAST") );
CV_FeatureDetectorTest gfttTest( "detector_gftt", createFeatureDetector("GFTT") );
CV_FeatureDetectorTest harrisTest( "detector_harris", createFeatureDetector("HARRIS") );
CV_FeatureDetectorTest mserTest( "detector_mser", createFeatureDetector("MSER") );
CV_FeatureDetectorTest siftTest( "detector_sift", createFeatureDetector("SIFT") );
CV_FeatureDetectorTest starTest( "detector_star", createFeatureDetector("STAR") );
CV_FeatureDetectorTest surfTest( "detector_surf", createFeatureDetector("SURF") );

/****************************************************************************************\
*                     Regression tests for descriptor extractors.                        *
\****************************************************************************************/
static void writeMatInBin( const Mat& mat, const string& filename )
{
    FILE* f = fopen( filename.c_str(), "wb");
    if( f )
    {
        int type = mat.type();
        fwrite( (void*)&mat.rows, sizeof(int), 1, f );
        fwrite( (void*)&mat.cols, sizeof(int), 1, f );
        fwrite( (void*)&type, sizeof(int), 1, f );
        fwrite( (void*)&mat.step, sizeof(int), 1, f );
        fwrite( (void*)mat.data, 1, mat.step*mat.rows, f );
        fclose(f);
    }
}

static Mat readMatFromBin( const string& filename )
{
    FILE* f = fopen( filename.c_str(), "rb" );
    if( f )
    {
        int rows, cols, type, step;
        fread( (void*)&rows, sizeof(int), 1, f );
        fread( (void*)&cols, sizeof(int), 1, f );
        fread( (void*)&type, sizeof(int), 1, f );
        fread( (void*)&step, sizeof(int), 1, f );

        uchar* data = (uchar*)cvAlloc(step*rows);
        fread( (void*)data, 1, step*rows, f );
        fclose(f);

        return Mat( rows, cols, type, data );
    }
    return Mat();
}

class CV_DescriptorExtractorTest : public CvTest
{
public:
    CV_DescriptorExtractorTest( const char* testName, float _normDif, const Ptr<DescriptorExtractor>& _dextractor, float _prevTime  ) :
            CvTest( testName, "cv::DescriptorExtractor::compute" ), normDif(_normDif), prevTime(_prevTime), dextractor(_dextractor) {}
protected:
    virtual void createDescriptorExtractor() {}

    void run(int)
    {
        createDescriptorExtractor();

        if( dextractor.empty() )
        {
            ts->printf(CvTS::LOG, "Descriptor extractor is empty\n");
            ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
            return;
        }

        string imgFilename =  string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME;
        Mat img = imread( imgFilename, 0 );
        if( img.empty() )
        {
            ts->printf( CvTS::LOG, "image %s can not be read\n", imgFilename.c_str() );
            ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
            return;
        }

        vector<KeyPoint> keypoints;
        FileStorage fs( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::READ );
        if( fs.isOpened() )
            read( fs.getFirstTopLevelNode(), keypoints );
        else
        {
            ts->printf( CvTS::LOG, "Compute and write keypoints\n" );
            fs.open( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::WRITE );
            if( fs.isOpened() )
            {
                SurfFeatureDetector fd;
                fd.detect(img, keypoints);
                write( fs, "keypoints", keypoints );
            }
            else
            {
                ts->printf(CvTS::LOG, "File for writting keypoints can not be opened\n");
                ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
                return;
            }
        }

        Mat calcDescriptors;
        double t = (double)getTickCount();
        dextractor->compute( img, keypoints, calcDescriptors );
        t = getTickCount() - t;
        ts->printf(CvTS::LOG, "\nAverage time of computiting one descriptor = %g ms (previous time = %g ms)\n", t/((double)cvGetTickFrequency()*1000.)/calcDescriptors.rows, prevTime );

        // TODO read and write descriptor extractor parameters and check them
        Mat validDescriptors = readDescriptors();
        if( !validDescriptors.empty() )
        {
            double normVal = norm( calcDescriptors, validDescriptors, NORM_INF );
            ts->printf( CvTS::LOG, "nofm (inf) BTW valid and calculated float descriptors = %f\n", normVal );
            if( normVal > normDif )
                ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
        }
        else
        {
            if( !writeDescriptors( calcDescriptors ) )
            {
                ts->printf( CvTS::LOG, "Descriptors can not be written\n" );
                ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
                return;
            }
        }
    }

    virtual Mat readDescriptors()
    {
        Mat res = readMatFromBin( string(ts->get_data_path()) + DESCRIPTOR_DIR + "/" + string(name) );
        return res;
    }

    virtual bool writeDescriptors( Mat& descs )
    {
        writeMatInBin( descs,  string(ts->get_data_path()) + DESCRIPTOR_DIR + "/" + string(name) );
        return true;
    }

    const float normDif;
    const float prevTime;

    Ptr<DescriptorExtractor> dextractor;
};

template<typename T>
class CV_CalonderDescriptorExtractorTest : public CV_DescriptorExtractorTest
{
public:
    CV_CalonderDescriptorExtractorTest( const char* testName, float _normDif, float _prevTime ) :
            CV_DescriptorExtractorTest( testName, _normDif, Ptr<DescriptorExtractor>(), _prevTime )
    {}

    virtual void createDescriptorExtractor()
    {
        dextractor = new CalonderDescriptorExtractor<T>( string(ts->get_data_path()) + FEATURES2D_DIR + "/calonder_classifier.rtc");
    }
};

CV_DescriptorExtractorTest siftDescriptorTest( "descriptor_sift", std::numeric_limits<float>::epsilon(),
                                                createDescriptorExtractor("SIFT"), 8.06652f  );
CV_DescriptorExtractorTest surfDescriptorTest( "descriptor_surf", std::numeric_limits<float>::epsilon(),
                                                createDescriptorExtractor("SURF"), 0.147372f );
#if CV_SSE2
CV_CalonderDescriptorExtractorTest<uchar> ucharCalonderTest( "descriptor_calonder_uchar",
                                                             std::numeric_limits<float>::epsilon() + 1,
                                                             0.0132175f );
CV_CalonderDescriptorExtractorTest<float> floatCalonderTest( "descriptor_calonder_float",
                                                             std::numeric_limits<float>::epsilon(),
                                                             0.0221308f );
#endif // CV_SSE2
<commit_msg>updated test thresholds<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "cvtest.h"
#include "opencv2/core/core.hpp"

using namespace std;
using namespace cv;

const string FEATURES2D_DIR = "features2d";
const string DETECTOR_DIR = FEATURES2D_DIR + "/feature_detectors";
const string DESCRIPTOR_DIR = FEATURES2D_DIR + "/descriptor_extractors";
const string IMAGE_FILENAME = "tsukuba.png";

/****************************************************************************************\
*            Regression tests for feature detectors comparing keypoints.                 *
\****************************************************************************************/

class CV_FeatureDetectorTest : public CvTest
{
public:
    CV_FeatureDetectorTest( const char* testName, const Ptr<FeatureDetector>& _fdetector ) :
        CvTest( testName, "cv::FeatureDetector::detect"), fdetector(_fdetector) {}

protected:
    virtual void run( int start_from )
    {
        const float maxPtDif = 1.f;
        const float maxSizeDif = 1.f;
        const float maxAngleDif = 2.f;
        const float maxResponseDif = 0.1f;

        string imgFilename = string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME;
        string resFilename = string(ts->get_data_path()) + DETECTOR_DIR + "/" + string(name) + "_res.xml.gz";

        if( fdetector.empty() )
        {
            ts->printf( CvTS::LOG, "Feature detector is empty" );
            ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
            return;
        }

        Mat image = imread( imgFilename, 0 );
        if( image.empty() )
        {
            ts->printf( CvTS::LOG, "image %s can not be read \n", imgFilename.c_str() );
            ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
            return;
        }

        FileStorage fs( resFilename, FileStorage::READ );

        vector<KeyPoint> calcKeypoints;
        fdetector->detect( image, calcKeypoints );

        if( fs.isOpened() ) // compare computed and valid keypoints
        {
            // TODO compare saved feature detector params with current ones
            vector<KeyPoint> validKeypoints;
            read( fs["keypoints"], validKeypoints );
            if( validKeypoints.empty() )
            {
                ts->printf( CvTS::LOG, "Keypoints can nod be read\n" );
                ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
                return;
            }

            int progress = 0, progressCount = validKeypoints.size() * calcKeypoints.size();
            int badPointCount = 0, commonPointCount = max(validKeypoints.size(), calcKeypoints.size());
            for( size_t v = 0; v < validKeypoints.size(); v++ )
            {
                int nearestIdx = -1;
                float minDist = std::numeric_limits<float>::max();

                for( size_t c = 0; c < calcKeypoints.size(); c++ )
                {
                    progress = update_progress( progress, v*calcKeypoints.size() + c, progressCount, 0 );
                    float curDist = norm( calcKeypoints[c].pt - validKeypoints[v].pt );
                    if( curDist < minDist )
                    {
                        minDist = curDist;
                        nearestIdx = c;
                    }
                }

                if( minDist > maxPtDif ||
                    fabs(calcKeypoints[nearestIdx].size - validKeypoints[v].size) > maxSizeDif ||
                    abs(calcKeypoints[nearestIdx].angle - validKeypoints[v].angle) > maxAngleDif ||
                    abs(calcKeypoints[nearestIdx].response - validKeypoints[v].response) > maxResponseDif ||
                    calcKeypoints[nearestIdx].octave != validKeypoints[v].octave

                    // TODO !!!!!!!
                    /*||
                    calcKeypoints[nearestIdx].class_id != validKeypoints[v].class_id*/ )
                {
                    badPointCount++;
                }
            }
            ts->printf( CvTS::LOG, "badPointCount = %d; validPointCount = %d; calcPointCount = %d\n",
                        badPointCount, validKeypoints.size(), calcKeypoints.size() );
            if( badPointCount > 0.9 * commonPointCount )
            {
                ts->printf( CvTS::LOG, "Bad accuracy!\n" );
                ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
                return;
            }
        }
        else // write
        {
            fs.open( resFilename, FileStorage::WRITE );
            if( !fs.isOpened() )
            {
                ts->printf( CvTS::LOG, "file %s can not be opened to write\n", resFilename.c_str() );
                ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
                return;
            }
            else
            {
                fs << "detector_params" << "{";
                fdetector->write( fs );
                fs << "}";

                write( fs, "keypoints", calcKeypoints );
            }
        }
        ts->set_failed_test_info( CvTS::OK );
    }

    Ptr<FeatureDetector> fdetector;
};

CV_FeatureDetectorTest fastTest( "detector_fast", createFeatureDetector("FAST") );
CV_FeatureDetectorTest gfttTest( "detector_gftt", createFeatureDetector("GFTT") );
CV_FeatureDetectorTest harrisTest( "detector_harris", createFeatureDetector("HARRIS") );
CV_FeatureDetectorTest mserTest( "detector_mser", createFeatureDetector("MSER") );
CV_FeatureDetectorTest siftTest( "detector_sift", createFeatureDetector("SIFT") );
CV_FeatureDetectorTest starTest( "detector_star", createFeatureDetector("STAR") );
CV_FeatureDetectorTest surfTest( "detector_surf", createFeatureDetector("SURF") );

/****************************************************************************************\
*                     Regression tests for descriptor extractors.                        *
\****************************************************************************************/
static void writeMatInBin( const Mat& mat, const string& filename )
{
    FILE* f = fopen( filename.c_str(), "wb");
    if( f )
    {
        int type = mat.type();
        fwrite( (void*)&mat.rows, sizeof(int), 1, f );
        fwrite( (void*)&mat.cols, sizeof(int), 1, f );
        fwrite( (void*)&type, sizeof(int), 1, f );
        fwrite( (void*)&mat.step, sizeof(int), 1, f );
        fwrite( (void*)mat.data, 1, mat.step*mat.rows, f );
        fclose(f);
    }
}

static Mat readMatFromBin( const string& filename )
{
    FILE* f = fopen( filename.c_str(), "rb" );
    if( f )
    {
        int rows, cols, type, step;
        fread( (void*)&rows, sizeof(int), 1, f );
        fread( (void*)&cols, sizeof(int), 1, f );
        fread( (void*)&type, sizeof(int), 1, f );
        fread( (void*)&step, sizeof(int), 1, f );

        uchar* data = (uchar*)cvAlloc(step*rows);
        fread( (void*)data, 1, step*rows, f );
        fclose(f);

        return Mat( rows, cols, type, data );
    }
    return Mat();
}

class CV_DescriptorExtractorTest : public CvTest
{
public:
    CV_DescriptorExtractorTest( const char* testName, float _normDif, const Ptr<DescriptorExtractor>& _dextractor, float _prevTime  ) :
            CvTest( testName, "cv::DescriptorExtractor::compute" ), normDif(_normDif), prevTime(_prevTime), dextractor(_dextractor) {}
protected:
    virtual void createDescriptorExtractor() {}

    void run(int)
    {
        createDescriptorExtractor();

        if( dextractor.empty() )
        {
            ts->printf(CvTS::LOG, "Descriptor extractor is empty\n");
            ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
            return;
        }

        string imgFilename =  string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME;
        Mat img = imread( imgFilename, 0 );
        if( img.empty() )
        {
            ts->printf( CvTS::LOG, "image %s can not be read\n", imgFilename.c_str() );
            ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
            return;
        }

        vector<KeyPoint> keypoints;
        FileStorage fs( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::READ );
        if( fs.isOpened() )
            read( fs.getFirstTopLevelNode(), keypoints );
        else
        {
            ts->printf( CvTS::LOG, "Compute and write keypoints\n" );
            fs.open( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::WRITE );
            if( fs.isOpened() )
            {
                SurfFeatureDetector fd;
                fd.detect(img, keypoints);
                write( fs, "keypoints", keypoints );
            }
            else
            {
                ts->printf(CvTS::LOG, "File for writting keypoints can not be opened\n");
                ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
                return;
            }
        }

        Mat calcDescriptors;
        double t = (double)getTickCount();
        dextractor->compute( img, keypoints, calcDescriptors );
        t = getTickCount() - t;
        ts->printf(CvTS::LOG, "\nAverage time of computiting one descriptor = %g ms (previous time = %g ms)\n", t/((double)cvGetTickFrequency()*1000.)/calcDescriptors.rows, prevTime );

        // TODO read and write descriptor extractor parameters and check them
        Mat validDescriptors = readDescriptors();
        if( !validDescriptors.empty() )
        {
            double normVal = norm( calcDescriptors, validDescriptors, NORM_INF );
            ts->printf( CvTS::LOG, "nofm (inf) BTW valid and calculated float descriptors = %f\n", normVal );
            if( normVal > normDif )
                ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY );
        }
        else
        {
            if( !writeDescriptors( calcDescriptors ) )
            {
                ts->printf( CvTS::LOG, "Descriptors can not be written\n" );
                ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA );
                return;
            }
        }
    }

    virtual Mat readDescriptors()
    {
        Mat res = readMatFromBin( string(ts->get_data_path()) + DESCRIPTOR_DIR + "/" + string(name) );
        return res;
    }

    virtual bool writeDescriptors( Mat& descs )
    {
        writeMatInBin( descs,  string(ts->get_data_path()) + DESCRIPTOR_DIR + "/" + string(name) );
        return true;
    }

    const float normDif;
    const float prevTime;

    Ptr<DescriptorExtractor> dextractor;
};

template<typename T>
class CV_CalonderDescriptorExtractorTest : public CV_DescriptorExtractorTest
{
public:
    CV_CalonderDescriptorExtractorTest( const char* testName, float _normDif, float _prevTime ) :
            CV_DescriptorExtractorTest( testName, _normDif, Ptr<DescriptorExtractor>(), _prevTime )
    {}

    virtual void createDescriptorExtractor()
    {
        dextractor = new CalonderDescriptorExtractor<T>( string(ts->get_data_path()) + FEATURES2D_DIR + "/calonder_classifier.rtc");
    }
};

CV_DescriptorExtractorTest siftDescriptorTest( "descriptor_sift", 0.004f,
                                                createDescriptorExtractor("SIFT"), 8.06652f  );
CV_DescriptorExtractorTest surfDescriptorTest( "descriptor_surf", 0.001f,
                                                createDescriptorExtractor("SURF"), 0.147372f );
#if CV_SSE2
CV_CalonderDescriptorExtractorTest<uchar> ucharCalonderTest( "descriptor_calonder_uchar",
                                                             std::numeric_limits<float>::epsilon() + 1,
                                                             0.0132175f );
CV_CalonderDescriptorExtractorTest<float> floatCalonderTest( "descriptor_calonder_float",
                                                             std::numeric_limits<float>::epsilon(),
                                                             0.0221308f );
#endif // CV_SSE2
<|endoftext|>