<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>

#include <qgalleryurlrequest.h>

#include <qabstractgallery.h>
#include <qgalleryabstractresponse.h>

QTM_USE_NAMESPACE

class tst_QGalleryUrlRequest : public QObject
{
    Q_OBJECT

private Q_SLOTS:
    void properties();
    void executeSynchronous();
    void executeAsynchronous();
};

class QtGalleryTestResponse : public QGalleryAbstractResponse
{
    Q_OBJECT
public:
    QtGalleryTestResponse(
            int count, const QVariant &itemId, const QString &itemType, int result, bool idle)
        : m_count(count), m_itemId(itemId), m_itemType(itemType)
    {
        if (result != QGalleryAbstractRequest::NoResult)
            finish(result, idle);
    }

    QtGalleryTestResponse(int result, bool idle)
        : m_count(0)
    {
        if (result != QGalleryAbstractRequest::NoResult)
            finish(result, idle);
    }

    QStringList propertyNames() const { return QStringList(); }
    int propertyKey(const QString &) const { return -1; }
    QGalleryProperty::Attributes propertyAttributes(int) const {
        return QGalleryProperty::Attributes(); }

    int count() const { return m_count; }

    QVariant id(int) const { return m_itemId; }
    QUrl url(int) const { return QUrl(); }
    QString type(int) const { return m_itemType; }
    QString parentId(int) const { return QString(); }
    QList<QGalleryResource> resources(int) const { return QList<QGalleryResource>(); }
    ItemStatus status(int) const { return ItemStatus(); }

    QVariant metaData(int, int) const { return QVariant(); }
    void setMetaData(int, int, const QVariant &) {}

    bool waitForFinished(int) { return false; }

public Q_SLOTS:
    void insert(const QVariant &itemId, const QString &itemType) {
        m_itemId = itemId; m_itemType = itemType; m_count = 1; inserted(0, 1); }

    void doFinish(int result, bool idle) { finish(result, idle); }

private:
    int m_count;
    QVariant m_itemId;
    QString m_itemType;
};

class QtTestGallery : public QAbstractGallery
{
    Q_OBJECT
public:
    QtTestGallery() : m_count(0), m_result(QGalleryAbstractRequest::NoResult), m_idle(false) {}

    bool isRequestSupported(QGalleryAbstractRequest::Type type) const {
        return type == QGalleryAbstractRequest::Url; }

    void setResult(int result) { m_result = result; }
    void setIdle(bool idle) { m_idle = idle; }

    void setItemId(const QVariant &itemId) { m_itemId = itemId; }
    void setItemType(const QString &itemType) { m_itemType = itemType; }
    void setCount(int count) { m_count = count; }

#ifdef Q_MOC_RUN
Q_SIGNALS:
#endif
    void insert(const QVariant &itemId, const QString &itemType);
    void finish(int result, bool idle);

protected:
    QGalleryAbstractResponse *createResponse(QGalleryAbstractRequest *request)
    {
        if (request->type() == QGalleryAbstractRequest::Url) {
            QtGalleryTestResponse *response = new QtGalleryTestResponse(
                    m_count, m_itemId, m_itemType, m_result, m_idle);

            connect(this, SIGNAL(insert(QVariant,QString)),
                    response, SLOT(insert(QVariant,QString)));
            connect(this, SIGNAL(finish(int,bool)), response, SLOT(doFinish(int,bool)));

            return response;
        }
        return 0;
    }

private:
    int m_count;
    QVariant m_itemId;
    QString m_itemType;
    int m_result;
    bool m_idle;
};

void tst_QGalleryUrlRequest::properties()
{
    const QUrl fileUrl(QLatin1String("file:///a/local/file"));
    const QUrl httpUrl(QLatin1String("http://example.com/"));

    QGalleryUrlRequest request;

    QCOMPARE(request.itemUrl(), QUrl());

    request.setItemUrl(fileUrl);
    QCOMPARE(request.itemUrl(), fileUrl);

    request.setItemUrl(httpUrl);
    QCOMPARE(request.itemUrl(), httpUrl);
}

void tst_QGalleryUrlRequest::executeSynchronous()
{
    const QVariant itemId(15);
    const QString itemType(QLatin1String("File"));

    QtTestGallery gallery;
    gallery.setResult(QGalleryAbstractRequest::ConnectionError);
    gallery.setItemId(itemId);
    gallery.setItemType(itemType);
    gallery.setCount(1);

    QGalleryUrlRequest request(&gallery);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    QSignalSpy spy(&request, SIGNAL(itemChanged()));

    request.execute();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::ConnectionError));
    QCOMPARE(spy.count(), 0);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    gallery.setResult(QGalleryAbstractRequest::Succeeded);
    request.execute();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::Succeeded));
    QCOMPARE(spy.count(), 1);
    QCOMPARE(request.itemId(), itemId);
    QCOMPARE(request.itemType(), itemType);

    request.clear();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::NoResult));
    QCOMPARE(spy.count(), 2);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());
}

void tst_QGalleryUrlRequest::executeAsynchronous()
{
    const QVariant itemId(15);
    const QString itemType(QLatin1String("File"));

    QtTestGallery gallery;
    gallery.setResult(QGalleryAbstractRequest::NoResult);
    gallery.setItemId(itemId);
    gallery.setItemType(itemType);

    QGalleryUrlRequest request(&gallery);

    QSignalSpy spy(&request, SIGNAL(itemChanged()));

    request.execute();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::NoResult));
    QCOMPARE(spy.count(), 0);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    gallery.insert(itemId, itemType);
    QCOMPARE(spy.count(), 1);
    QCOMPARE(request.itemId(), itemId);
    QCOMPARE(request.itemType(), itemType);

    gallery.finish(QGalleryAbstractRequest::Succeeded, true);
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::Succeeded));
    QCOMPARE(spy.count(), 1);
    QCOMPARE(request.itemId(), itemId);
    QCOMPARE(request.itemType(), itemType);

    request.clear();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::NoResult));
    QCOMPARE(spy.count(), 2);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());
}

QTEST_MAIN(tst_QGalleryUrlRequest)

#include "tst_qgalleryurlrequest.moc"
<commit_msg>Extend QGalleryUrlRequest test.<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>

#include <qgalleryurlrequest.h>

#include <qabstractgallery.h>
#include <qgalleryabstractresponse.h>

QTM_USE_NAMESPACE

class tst_QGalleryUrlRequest : public QObject
{
    Q_OBJECT

private Q_SLOTS:
    void properties();
    void executeSynchronous();
    void executeAsynchronous();
};

class QtGalleryTestResponse : public QGalleryAbstractResponse
{
    Q_OBJECT
public:
    QtGalleryTestResponse(
            int count, const QVariant &itemId, const QString &itemType, int result, bool idle)
        : m_count(count), m_itemId(itemId), m_itemType(itemType)
    {
        if (result != QGalleryAbstractRequest::NoResult)
            finish(result, idle);
    }

    QtGalleryTestResponse(int result, bool idle)
        : m_count(0)
    {
        if (result != QGalleryAbstractRequest::NoResult)
            finish(result, idle);
    }

    QStringList propertyNames() const { return QStringList(); }
    int propertyKey(const QString &) const { return -1; }
    QGalleryProperty::Attributes propertyAttributes(int) const {
        return QGalleryProperty::Attributes(); }

    int count() const { return m_count; }

    QVariant id(int) const { return m_itemId; }
    QUrl url(int) const { return QUrl(); }
    QString type(int) const { return m_itemType; }
    QString parentId(int) const { return QString(); }
    QList<QGalleryResource> resources(int) const { return QList<QGalleryResource>(); }
    ItemStatus status(int) const { return ItemStatus(); }

    QVariant metaData(int, int) const { return QVariant(); }
    void setMetaData(int, int, const QVariant &) {}

    bool waitForFinished(int) { return false; }

public Q_SLOTS:
    void insert(int index, int count, const QVariant &itemId, const QString &itemType) {
        m_itemId = itemId; m_itemType = itemType; m_count = 1; inserted(index, count); }

    void doFinish(int result, bool idle) { finish(result, idle); }

private:
    int m_count;
    QVariant m_itemId;
    QString m_itemType;
};

class QtTestGallery : public QAbstractGallery
{
    Q_OBJECT
public:
    QtTestGallery() : m_count(0), m_result(QGalleryAbstractRequest::NoResult), m_idle(false) {}

    bool isRequestSupported(QGalleryAbstractRequest::Type type) const {
        return type == QGalleryAbstractRequest::Url; }

    void setResult(int result) { m_result = result; }
    void setIdle(bool idle) { m_idle = idle; }

    void setItemId(const QVariant &itemId) { m_itemId = itemId; }
    void setItemType(const QString &itemType) { m_itemType = itemType; }
    void setCount(int count) { m_count = count; }

#ifdef Q_MOC_RUN
Q_SIGNALS:
#endif
    void insert(int index, int count, const QVariant &itemId, const QString &itemType);
    void finish(int result, bool idle);

protected:
    QGalleryAbstractResponse *createResponse(QGalleryAbstractRequest *request)
    {
        if (request->type() == QGalleryAbstractRequest::Url) {
            QtGalleryTestResponse *response = new QtGalleryTestResponse(
                    m_count, m_itemId, m_itemType, m_result, m_idle);

            connect(this, SIGNAL(insert(int,int,QVariant,QString)),
                    response, SLOT(insert(int,int,QVariant,QString)));
            connect(this, SIGNAL(finish(int,bool)), response, SLOT(doFinish(int,bool)));

            return response;
        }
        return 0;
    }

private:
    int m_count;
    QVariant m_itemId;
    QString m_itemType;
    int m_result;
    bool m_idle;
};

void tst_QGalleryUrlRequest::properties()
{
    const QUrl fileUrl(QLatin1String("file:///a/local/file"));
    const QUrl httpUrl(QLatin1String("http://example.com/"));

    QGalleryUrlRequest request;

    QCOMPARE(request.itemUrl(), QUrl());
    QCOMPARE(request.create(), false);

    request.setItemUrl(fileUrl);
    QCOMPARE(request.itemUrl(), fileUrl);

    request.setItemUrl(httpUrl);
    QCOMPARE(request.itemUrl(), httpUrl);

    request.setCreate(true);
    QCOMPARE(request.create(), true);

    request.setCreate(false);
    QCOMPARE(request.create(), false);
}

void tst_QGalleryUrlRequest::executeSynchronous()
{
    const QVariant itemId(15);
    const QString itemType(QLatin1String("File"));

    QtTestGallery gallery;
    gallery.setResult(QGalleryAbstractRequest::ConnectionError);
    gallery.setItemId(itemId);
    gallery.setItemType(itemType);
    gallery.setCount(1);

    QGalleryUrlRequest request(&gallery);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    QSignalSpy spy(&request, SIGNAL(itemChanged()));

    request.execute();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::ConnectionError));
    QCOMPARE(spy.count(), 0);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    gallery.setResult(QGalleryAbstractRequest::Succeeded);
    request.execute();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::Succeeded));
    QCOMPARE(spy.count(), 1);
    QCOMPARE(request.itemId(), itemId);
    QCOMPARE(request.itemType(), itemType);

    request.clear();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::NoResult));
    QCOMPARE(spy.count(), 2);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    gallery.setItemId(QVariant());
    request.execute();
    QCOMPARE(spy.count(), 3);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), itemType);

    request.clear();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::NoResult));
    QCOMPARE(spy.count(), 4);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());
}

void tst_QGalleryUrlRequest::executeAsynchronous()
{
    const QVariant itemId(15);
    const QString itemType(QLatin1String("File"));

    QtTestGallery gallery;
    gallery.setResult(QGalleryAbstractRequest::NoResult);
    gallery.setItemId(itemId);
    gallery.setItemType(itemType);

    QGalleryUrlRequest request(&gallery);

    QSignalSpy spy(&request, SIGNAL(itemChanged()));

    request.execute();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::NoResult));
    QCOMPARE(spy.count(), 0);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    gallery.insert(0, 1, itemId, itemType);
    QCOMPARE(spy.count(), 1);
    QCOMPARE(request.itemId(), itemId);
    QCOMPARE(request.itemType(), itemType);

    gallery.finish(QGalleryAbstractRequest::Succeeded, true);
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::Succeeded));
    QCOMPARE(spy.count(), 1);
    QCOMPARE(request.itemId(), itemId);
    QCOMPARE(request.itemType(), itemType);

    request.clear();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::NoResult));
    QCOMPARE(spy.count(), 2);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    request.execute();
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::NoResult));
    QCOMPARE(spy.count(), 2);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    QTest::ignoreMessage(
            QtWarningMsg,
            "QGalleryUrlRequest::insert: Response contained an irregular number of items."
            "Index: 0, Count 5");

    gallery.insert(0, 5, itemId, itemType);
    gallery.finish(QGalleryAbstractRequest::Succeeded, true);
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::Succeeded));
    QCOMPARE(spy.count(), 2);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());

    QTest::ignoreMessage(
            QtWarningMsg,
            "QGalleryUrlRequest::insert: Response contained an irregular number of items."
            "Index: 3, Count 1");

    gallery.insert(3, 1, itemId, itemType);
    gallery.finish(QGalleryAbstractRequest::Succeeded, true);
    QCOMPARE(request.result(), int(QGalleryAbstractRequest::Succeeded));
    QCOMPARE(spy.count(), 2);
    QCOMPARE(request.itemId(), QVariant());
    QCOMPARE(request.itemType(), QString());
}

QTEST_MAIN(tst_QGalleryUrlRequest)

#include "tst_qgalleryurlrequest.moc"
<|endoftext|>


<commit_before><commit_msg>fix #201 Division by zero in FScene::computeLightRanges (#217)<commit_after><|endoftext|>


<commit_before>/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 Module:       FGFilter.cpp
 Author:       Jon S. Berndt
 Date started: 11/2000

 ------------- Copyright (C) 2000 -------------

 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.

 Further information about the GNU General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------

HISTORY
--------------------------------------------------------------------------------

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES,  and NOTES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

#include "FGFilter.h"

static const char *IdSrc = "$Id: FGFilter.cpp,v 1.26 2001/12/12 18:31:09 jberndt Exp $";
static const char *IdHdr = ID_FILTER;

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
                                                       AC_cfg(AC_cfg)
{
  string token;
  double denom;

  Type = AC_cfg->GetValue("TYPE");
  Name = AC_cfg->GetValue("NAME");
  AC_cfg->GetNextConfigLine();
  dt = fcs->GetState()->Getdt();

  C1 = C2 = C3 = C4 = C5 = C6 = 0.0;

  if      (Type == "LAG_FILTER")          FilterType = eLag        ;
  else if (Type == "LEAD_LAG_FILTER")     FilterType = eLeadLag    ;
  else if (Type == "SECOND_ORDER_FILTER") FilterType = eOrder2     ;
  else if (Type == "WASHOUT_FILTER")      FilterType = eWashout    ;
  else if (Type == "INTEGRATOR")          FilterType = eIntegrator ;
  else                                    FilterType = eUnknown    ;

  while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
    *AC_cfg >> token;
    if      (token == "ID")     *AC_cfg >> ID;
    else if (token == "C1")     *AC_cfg >> C1;
    else if (token == "C2")     *AC_cfg >> C2;
    else if (token == "C3")     *AC_cfg >> C3;
    else if (token == "C4")     *AC_cfg >> C4;
    else if (token == "C5")     *AC_cfg >> C5;
    else if (token == "C6")     *AC_cfg >> C6;
    else if (token == "INPUT")
    {
      token = AC_cfg->GetValue("INPUT");
      if (token.find("FG_") != token.npos) {
        *AC_cfg >> token;
        InputIdx = fcs->GetState()->GetParameterIndex(token);
        InputType = itPilotAC;
      } else {
        *AC_cfg >> InputIdx;
        InputType = itFCS;
      }
    }
    else if (token == "OUTPUT")
    {
      IsOutput = true;
      *AC_cfg >> sOutputIdx;
      OutputIdx = fcs->GetState()->GetParameterIndex(sOutputIdx);
    }
    else cerr << "Unknown filter type: " << token << endl;
  }

  Initialize = true;

  switch (FilterType) {
    case eLag:
      denom = 2.00 + dt*C1;
      ca = dt*C1 / denom;
      cb = (2.00 - dt*C1) / denom;
      break;
    case eLeadLag:
      denom = 2.00*C3 + dt*C4;
      ca = (2.00*C1 + dt*C2) / denom;
      cb = (dt*C2 - 2.00*C1) / denom;
      cc = (2.00*C3 - dt*C2) / denom;
      break;
    case eOrder2:
      denom = 4.0*C3 + 2.0*C5*dt + C6*dt*dt;
      ca = 4.0*C1 + 2.0*C2*dt + C3*dt*dt / denom;
      cb = 2.0*C3*dt*dt - 8.0*C1 / denom;
      cc = 4.0*C1 - 2.0*C2*dt + C3*dt*dt / denom;
      cd = 2.0*C6*dt*dt - 8.0*C4 / denom;
      ce = 4.0*C3 - 2.0*C5*dt + C6*dt*dt / denom;
      break;
    case eWashout:
      denom = 2.00 + dt*C1;
      ca = 2.00 / denom;
      cb = (2.00 - dt*C1) / denom;
      break;
    case eIntegrator:
      ca = dt*C1 / 2.00;
      break;
    case eUnknown:
      cerr << "Unknown filter type" << endl;
    break;
  }

  Debug(0);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

FGFilter::~FGFilter()
{
  Debug(1);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

bool FGFilter::Run(void)
{
  FGFCSComponent::Run(); // call the base class for initialization of Input

  if (Initialize) {

    PreviousOutput1 = PreviousInput1 = Output = Input;
    Initialize = false;

  } else {

    switch (FilterType) {
      case eLag:
        Output = Input * ca + PreviousInput1 * ca + PreviousOutput1 * cb;
        break;
      case eLeadLag:
        Output = Input * ca + PreviousInput1 * cb + PreviousOutput1 * cc;
        break;
      case eOrder2:
        Output = Input * ca + PreviousInput1 * cb + PreviousInput2 * cc
	                          - PreviousOutput1 * cd - PreviousOutput2 * ce;
        break;
      case eWashout:
        Output = Input * ca - PreviousInput1 * ca + PreviousOutput1 * cb;
        break;
      case eIntegrator:
        Output = Input * ca + PreviousInput1 * ca + PreviousOutput1;
        break;
    }

  }

  PreviousOutput2 = PreviousOutput1;
  PreviousOutput1 = Output;
  PreviousInput2  = PreviousInput1;
  PreviousInput1  = Input;

  if (IsOutput) SetOutput();

  return true;
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//    The bitmasked value choices are as follows:
//    unset: In this case (the default) JSBSim would only print
//       out the normally expected messages, essentially echoing
//       the config files as they are read. If the environment
//       variable is not set, debug_lvl is set to 1 internally
//    0: This requests JSBSim not to output any messages
//       whatsoever.
//    1: This value explicity requests the normal JSBSim
//       startup messages
//    2: This value asks for a message to be printed out when
//       a class is instantiated
//    4: When this value is set, a message is displayed when a
//       FGModel object executes its Run() method
//    8: When this value is set, various runtime state variables
//       are printed out periodically
//    16: When set various parameters are sanity checked and
//       a message is printed out when they go out of bounds

void FGFilter::Debug(int from)
{
  if (debug_lvl <= 0) return;

  if (debug_lvl & 1) { // Standard console startup message output
    if (from == 0) { // Constructor
      cout << "      ID: " << ID << endl;
      cout << "      INPUT: " << InputIdx << endl;
      cout << "      C1: " << C1 << endl;
      cout << "      C2: " << C2 << endl;
      cout << "      C3: " << C3 << endl;
      cout << "      C4: " << C4 << endl;
      cout << "      C5: " << C5 << endl;
      cout << "      C6: " << C6 << endl;
      if (IsOutput) cout << "      OUTPUT: " << sOutputIdx << endl;
    }
  }
  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
    if (from == 0) cout << "Instantiated: FGFilter" << endl;
    if (from == 1) cout << "Destroyed:    FGFilter" << endl;
  }
  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
  }
  if (debug_lvl & 8 ) { // Runtime state variables
  }
  if (debug_lvl & 16) { // Sanity checking
  }
}

<commit_msg>Compiler warnings<commit_after>/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 Module:       FGFilter.cpp
 Author:       Jon S. Berndt
 Date started: 11/2000

 ------------- Copyright (C) 2000 -------------

 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.

 Further information about the GNU General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------

HISTORY
--------------------------------------------------------------------------------

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES,  and NOTES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

#include "FGFilter.h"

static const char *IdSrc = "$Id: FGFilter.cpp,v 1.27 2001/12/22 13:31:38 apeden Exp $";
static const char *IdHdr = ID_FILTER;

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
                                                       AC_cfg(AC_cfg)
{
  string token;
  double denom;

  Type = AC_cfg->GetValue("TYPE");
  Name = AC_cfg->GetValue("NAME");
  AC_cfg->GetNextConfigLine();
  dt = fcs->GetState()->Getdt();

  C1 = C2 = C3 = C4 = C5 = C6 = 0.0;

  if      (Type == "LAG_FILTER")          FilterType = eLag        ;
  else if (Type == "LEAD_LAG_FILTER")     FilterType = eLeadLag    ;
  else if (Type == "SECOND_ORDER_FILTER") FilterType = eOrder2     ;
  else if (Type == "WASHOUT_FILTER")      FilterType = eWashout    ;
  else if (Type == "INTEGRATOR")          FilterType = eIntegrator ;
  else                                    FilterType = eUnknown    ;

  while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
    *AC_cfg >> token;
    if      (token == "ID")     *AC_cfg >> ID;
    else if (token == "C1")     *AC_cfg >> C1;
    else if (token == "C2")     *AC_cfg >> C2;
    else if (token == "C3")     *AC_cfg >> C3;
    else if (token == "C4")     *AC_cfg >> C4;
    else if (token == "C5")     *AC_cfg >> C5;
    else if (token == "C6")     *AC_cfg >> C6;
    else if (token == "INPUT")
    {
      token = AC_cfg->GetValue("INPUT");
      if (token.find("FG_") != token.npos) {
        *AC_cfg >> token;
        InputIdx = fcs->GetState()->GetParameterIndex(token);
        InputType = itPilotAC;
      } else {
        *AC_cfg >> InputIdx;
        InputType = itFCS;
      }
    }
    else if (token == "OUTPUT")
    {
      IsOutput = true;
      *AC_cfg >> sOutputIdx;
      OutputIdx = fcs->GetState()->GetParameterIndex(sOutputIdx);
    }
    else cerr << "Unknown filter type: " << token << endl;
  }

  Initialize = true;

  switch (FilterType) {
    case eLag:
      denom = 2.00 + dt*C1;
      ca = dt*C1 / denom;
      cb = (2.00 - dt*C1) / denom;
      break;
    case eLeadLag:
      denom = 2.00*C3 + dt*C4;
      ca = (2.00*C1 + dt*C2) / denom;
      cb = (dt*C2 - 2.00*C1) / denom;
      cc = (2.00*C3 - dt*C2) / denom;
      break;
    case eOrder2:
      denom = 4.0*C3 + 2.0*C5*dt + C6*dt*dt;
      ca = 4.0*C1 + 2.0*C2*dt + C3*dt*dt / denom;
      cb = 2.0*C3*dt*dt - 8.0*C1 / denom;
      cc = 4.0*C1 - 2.0*C2*dt + C3*dt*dt / denom;
      cd = 2.0*C6*dt*dt - 8.0*C4 / denom;
      ce = 4.0*C3 - 2.0*C5*dt + C6*dt*dt / denom;
      break;
    case eWashout:
      denom = 2.00 + dt*C1;
      ca = 2.00 / denom;
      cb = (2.00 - dt*C1) / denom;
      break;
    case eIntegrator:
      ca = dt*C1 / 2.00;
      break;
    case eUnknown:
      cerr << "Unknown filter type" << endl;
    break;
  }

  Debug(0);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

FGFilter::~FGFilter()
{
  Debug(1);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

bool FGFilter::Run(void)
{
  FGFCSComponent::Run(); // call the base class for initialization of Input

  if (Initialize) {

    PreviousOutput1 = PreviousInput1 = Output = Input;
    Initialize = false;

  } else {

    switch (FilterType) {
      case eLag:
        Output = Input * ca + PreviousInput1 * ca + PreviousOutput1 * cb;
        break;
      case eLeadLag:
        Output = Input * ca + PreviousInput1 * cb + PreviousOutput1 * cc;
        break;
      case eOrder2:
        Output = Input * ca + PreviousInput1 * cb + PreviousInput2 * cc
	                          - PreviousOutput1 * cd - PreviousOutput2 * ce;
        break;
      case eWashout:
        Output = Input * ca - PreviousInput1 * ca + PreviousOutput1 * cb;
        break;
      case eIntegrator:
        Output = Input * ca + PreviousInput1 * ca + PreviousOutput1;
        break;
      case eUnknown:
        break;
    }

  }

  PreviousOutput2 = PreviousOutput1;
  PreviousOutput1 = Output;
  PreviousInput2  = PreviousInput1;
  PreviousInput1  = Input;

  if (IsOutput) SetOutput();

  return true;
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//    The bitmasked value choices are as follows:
//    unset: In this case (the default) JSBSim would only print
//       out the normally expected messages, essentially echoing
//       the config files as they are read. If the environment
//       variable is not set, debug_lvl is set to 1 internally
//    0: This requests JSBSim not to output any messages
//       whatsoever.
//    1: This value explicity requests the normal JSBSim
//       startup messages
//    2: This value asks for a message to be printed out when
//       a class is instantiated
//    4: When this value is set, a message is displayed when a
//       FGModel object executes its Run() method
//    8: When this value is set, various runtime state variables
//       are printed out periodically
//    16: When set various parameters are sanity checked and
//       a message is printed out when they go out of bounds

void FGFilter::Debug(int from)
{
  if (debug_lvl <= 0) return;

  if (debug_lvl & 1) { // Standard console startup message output
    if (from == 0) { // Constructor
      cout << "      ID: " << ID << endl;
      cout << "      INPUT: " << InputIdx << endl;
      cout << "      C1: " << C1 << endl;
      cout << "      C2: " << C2 << endl;
      cout << "      C3: " << C3 << endl;
      cout << "      C4: " << C4 << endl;
      cout << "      C5: " << C5 << endl;
      cout << "      C6: " << C6 << endl;
      if (IsOutput) cout << "      OUTPUT: " << sOutputIdx << endl;
    }
  }
  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
    if (from == 0) cout << "Instantiated: FGFilter" << endl;
    if (from == 1) cout << "Destroyed:    FGFilter" << endl;
  }
  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
  }
  if (debug_lvl & 8 ) { // Runtime state variables
  }
  if (debug_lvl & 16) { // Sanity checking
  }
}

<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <set>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>

#define OMPI_SKIP_MPICXX 1
#include <mpi.h>

#include "syncio.h"
#include "posixio.h"
#include "phIO.h"

char read_solution(double** solutiono, int* size, int* nshgo, int* ndofo,
		int nump, int rank, int timestep, int nSyncFiles, char* casedir);
std::set<int>* find_timesteps(char* casedir, int nSyncFiles);
double compare_solution(char* lpath, char* rpath,
    int timestep, int nump, int nSyncFiles);
char* getRestartName(int nSyncFiles);

int main(int argc, char** argv)
{
       	int rank;
	int size;
	MPI_Init(&argc, &argv);

	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);

	if(argc != 5) {
          fprintf(stderr, "argc %d\n", argc);
          fprintf(stderr,
              "Usage: %s <left> <right> <numSyncFiles> <tolerance>\n"
              "where <left> and <right> are different"
              "N-procs_case directories\n", argv[0]);
          MPI_Finalize();
          return 1;
        }
	char* lpath = argv[1];
	char* rpath = argv[2];
        int nSyncFiles = atoi(argv[3]);
        double tolerance = atof(argv[4]);

	int ndof;
	int nshg;
	int solsize;
	double* solution;

	std::set<int>* l_timesteps = find_timesteps(lpath, nSyncFiles);
	std::set<int>* r_timesteps = find_timesteps(rpath, nSyncFiles);
	std::set<int>* timesteps_to_check = new std::set<int>;
	std::set_intersection(l_timesteps->begin(), l_timesteps->end(),
			r_timesteps->begin(), r_timesteps->end(),
			std::inserter(*timesteps_to_check, timesteps_to_check->begin()));
        delete l_timesteps;
        delete r_timesteps;
	if(rank == 0)
		printf("Found %d common timesteps\n",
			       	timesteps_to_check->size());
#ifdef DBGONLY
	read_solution(&solution, &solsize, &nshg, &ndof,
            size, rank, 0, numSyncFiles, "./");
	printf("nshg: %d, ndof: %d\n", nshg, ndof);
	assert(solsize == ndof*nshg);
#endif
	double maxerror = 0.0;
	double error;
	double gblmaxerror;
	for(std::set<int>::iterator i = timesteps_to_check->begin();
			i!=timesteps_to_check->end();i++)
	{
		error = compare_solution(lpath, rpath, *i, size, nSyncFiles);
		if(error>maxerror) maxerror = error;
	}
        delete timesteps_to_check;
	MPI_Barrier(MPI_COMM_WORLD);
	MPI_Reduce(&maxerror, &gblmaxerror, 1, MPI_DOUBLE, MPI_MAX, 0,
		MPI_COMM_WORLD);
	if(rank == 0) printf("Maximum difference across all timesteps: %e\n",
			gblmaxerror);
	MPI_Finalize();
        return (gblmaxerror > tolerance);
}
double compare_solution(char* lpath, char* rpath, int timestep, int nump, int nSyncFiles)
{
	int rank;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	double* lsol;
	double* rsol;
	int lsize;
	int rsize;

	read_solution(&lsol, &lsize, NULL, NULL,
            nump, rank, timestep, nSyncFiles, lpath);
	read_solution(&rsol, &rsize, NULL, NULL,
            nump, rank, timestep, nSyncFiles, rpath);

	double maxdiff=0.0;
	double gblmaxdiff;
	if(lsize != rsize)
	{
		printf("Error: Solution sizes different: %d, %d\n",
				lsize, rsize);
		assert(lsize == rsize);
	}
	for(int i=0;i<lsize;i++)
	{
		double diff = fabs(lsol[i]-rsol[i]);
		if(diff > maxdiff) maxdiff = diff;
	}
        free(lsol);
        free(rsol);
	MPI_Reduce(&maxdiff, &gblmaxdiff, 1, MPI_DOUBLE, MPI_MAX, 0,
		       	MPI_COMM_WORLD);
	MPI_Barrier(MPI_COMM_WORLD); //TODO: debugging only
	if(rank == 0)
	printf("Timestep: %d, maximum difference: %e\n", timestep, gblmaxdiff);
	return gblmaxdiff;

}
char read_solution(double** solutiono, int* size, int* nshgo, int* ndofo,
		int nump, int rank, int timestep, int nSyncFiles, char* casedir)
{
	int iarray[10];
        const char* iformat = "binary";
        int ithree=3;
        int igeombc;
        char* fn;
	int nshg;
	int ndof;
	double* solution;
        phio_fp fp;
        if( nSyncFiles == 0 )
          posixio_setup(&fp, 'r');
        else if( nSyncFiles > 0 )
          syncio_setup_read(nSyncFiles, &fp);
        char rname[1024];
        phio_constructName(fp,"restart",rname);
        asprintf(&fn,"%s/%s%d.",casedir,rname,timestep);
        phio_openfile(fn, fp);

	phio_readheader(fp, "solution", (void*) iarray, &ithree, "integer", iformat);
	nshg = iarray[0];
	ndof = iarray[1];
	if(size != NULL)
		*size = nshg*ndof;
	solution = (double*) malloc(sizeof(double)*nshg*ndof);
	phio_readdatablock(fp, "solution", solution, size, "double", iformat);
	phio_closefile(fp);
	if(solutiono != NULL)
		*solutiono = solution;
	if(nshgo != NULL)
		*nshgo = nshg;
	if(ndofo != NULL)
		*ndofo = ndof;
	free(fn);
	return(0);
}

std::set<int>* find_timesteps(char* casedir, int nSyncFiles)
{
	char* path;
	DIR* dir;
	struct dirent* d;
	int part, ts;
	std::set<int>* step_list = new std::set<int>;

        asprintf(&path, "%s", casedir);
	dir = opendir(path);
	if(!dir)
	{
		perror("Error opening case: ");
		MPI_Abort(MPI_COMM_WORLD,1);
	}
        char* rname = getRestartName(nSyncFiles);
        char* fmt;
        asprintf(&fmt, "%s.%%d.%%d", rname);
	while((d=readdir(dir)))
	{
		if(sscanf(d->d_name, fmt, &ts, &part)==2)
		{
			step_list->insert(ts);
		}
	}
        free(rname);
        free(fmt);
	free(path);
        closedir(dir);
	return(step_list);
}

char* getRestartName(int nSyncFiles) {
  char* f;
  if(0 == nSyncFiles)
    asprintf(&f, "restart");
  else if(nSyncFiles > 0)
    asprintf(&f, "restart-dat");
  else {
    fprintf(stderr,
        "ERROR: the number of sync-io files must be"
        "greater than or equal to zero\n");
    MPI_Abort(MPI_COMM_WORLD, 1);
    return NULL;
  }
  return f;
}
<commit_msg>add preprocessor constants to enable non-standard printfs<commit_after>#define _GNU_SOURCE
#define _WITH_DPRINTF
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <set>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>

#define OMPI_SKIP_MPICXX 1
#include <mpi.h>

#include "syncio.h"
#include "posixio.h"
#include "phIO.h"

char read_solution(double** solutiono, int* size, int* nshgo, int* ndofo,
		int nump, int rank, int timestep, int nSyncFiles, char* casedir);
std::set<int>* find_timesteps(char* casedir, int nSyncFiles);
double compare_solution(char* lpath, char* rpath,
    int timestep, int nump, int nSyncFiles);
char* getRestartName(int nSyncFiles);

int main(int argc, char** argv)
{
       	int rank;
	int size;
	MPI_Init(&argc, &argv);

	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);

	if(argc != 5) {
          fprintf(stderr, "argc %d\n", argc);
          fprintf(stderr,
              "Usage: %s <left> <right> <numSyncFiles> <tolerance>\n"
              "where <left> and <right> are different"
              "N-procs_case directories\n", argv[0]);
          MPI_Finalize();
          return 1;
        }
	char* lpath = argv[1];
	char* rpath = argv[2];
        int nSyncFiles = atoi(argv[3]);
        double tolerance = atof(argv[4]);

	int ndof;
	int nshg;
	int solsize;
	double* solution;

	std::set<int>* l_timesteps = find_timesteps(lpath, nSyncFiles);
	std::set<int>* r_timesteps = find_timesteps(rpath, nSyncFiles);
	std::set<int>* timesteps_to_check = new std::set<int>;
	std::set_intersection(l_timesteps->begin(), l_timesteps->end(),
			r_timesteps->begin(), r_timesteps->end(),
			std::inserter(*timesteps_to_check, timesteps_to_check->begin()));
        delete l_timesteps;
        delete r_timesteps;
	if(rank == 0)
		printf("Found %d common timesteps\n",
			       	timesteps_to_check->size());
#ifdef DBGONLY
	read_solution(&solution, &solsize, &nshg, &ndof,
            size, rank, 0, numSyncFiles, "./");
	printf("nshg: %d, ndof: %d\n", nshg, ndof);
	assert(solsize == ndof*nshg);
#endif
	double maxerror = 0.0;
	double error;
	double gblmaxerror;
	for(std::set<int>::iterator i = timesteps_to_check->begin();
			i!=timesteps_to_check->end();i++)
	{
		error = compare_solution(lpath, rpath, *i, size, nSyncFiles);
		if(error>maxerror) maxerror = error;
	}
        delete timesteps_to_check;
	MPI_Barrier(MPI_COMM_WORLD);
	MPI_Reduce(&maxerror, &gblmaxerror, 1, MPI_DOUBLE, MPI_MAX, 0,
		MPI_COMM_WORLD);
	if(rank == 0) printf("Maximum difference across all timesteps: %e\n",
			gblmaxerror);
	MPI_Finalize();
        return (gblmaxerror > tolerance);
}
double compare_solution(char* lpath, char* rpath, int timestep, int nump, int nSyncFiles)
{
	int rank;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	double* lsol;
	double* rsol;
	int lsize;
	int rsize;

	read_solution(&lsol, &lsize, NULL, NULL,
            nump, rank, timestep, nSyncFiles, lpath);
	read_solution(&rsol, &rsize, NULL, NULL,
            nump, rank, timestep, nSyncFiles, rpath);

	double maxdiff=0.0;
	double gblmaxdiff;
	if(lsize != rsize)
	{
		printf("Error: Solution sizes different: %d, %d\n",
				lsize, rsize);
		assert(lsize == rsize);
	}
	for(int i=0;i<lsize;i++)
	{
		double diff = fabs(lsol[i]-rsol[i]);
		if(diff > maxdiff) maxdiff = diff;
	}
        free(lsol);
        free(rsol);
	MPI_Reduce(&maxdiff, &gblmaxdiff, 1, MPI_DOUBLE, MPI_MAX, 0,
		       	MPI_COMM_WORLD);
	MPI_Barrier(MPI_COMM_WORLD); //TODO: debugging only
	if(rank == 0)
	printf("Timestep: %d, maximum difference: %e\n", timestep, gblmaxdiff);
	return gblmaxdiff;

}
char read_solution(double** solutiono, int* size, int* nshgo, int* ndofo,
		int nump, int rank, int timestep, int nSyncFiles, char* casedir)
{
	int iarray[10];
        const char* iformat = "binary";
        int ithree=3;
        int igeombc;
        char* fn;
	int nshg;
	int ndof;
	double* solution;
        phio_fp fp;
        if( nSyncFiles == 0 )
          posixio_setup(&fp, 'r');
        else if( nSyncFiles > 0 )
          syncio_setup_read(nSyncFiles, &fp);
        char rname[1024];
        phio_constructName(fp,"restart",rname);
        asprintf(&fn,"%s/%s%d.",casedir,rname,timestep);
        phio_openfile(fn, fp);

	phio_readheader(fp, "solution", (void*) iarray, &ithree, "integer", iformat);
	nshg = iarray[0];
	ndof = iarray[1];
	if(size != NULL)
		*size = nshg*ndof;
	solution = (double*) malloc(sizeof(double)*nshg*ndof);
	phio_readdatablock(fp, "solution", solution, size, "double", iformat);
	phio_closefile(fp);
	if(solutiono != NULL)
		*solutiono = solution;
	if(nshgo != NULL)
		*nshgo = nshg;
	if(ndofo != NULL)
		*ndofo = ndof;
	free(fn);
	return(0);
}

std::set<int>* find_timesteps(char* casedir, int nSyncFiles)
{
	char* path;
	DIR* dir;
	struct dirent* d;
	int part, ts;
	std::set<int>* step_list = new std::set<int>;

        asprintf(&path, "%s", casedir);
	dir = opendir(path);
	if(!dir)
	{
		perror("Error opening case: ");
		MPI_Abort(MPI_COMM_WORLD,1);
	}
        char* rname = getRestartName(nSyncFiles);
        char* fmt;
        asprintf(&fmt, "%s.%%d.%%d", rname);
	while((d=readdir(dir)))
	{
		if(sscanf(d->d_name, fmt, &ts, &part)==2)
		{
			step_list->insert(ts);
		}
	}
        free(rname);
        free(fmt);
	free(path);
        closedir(dir);
	return(step_list);
}

char* getRestartName(int nSyncFiles) {
  char* f;
  if(0 == nSyncFiles)
    asprintf(&f, "restart");
  else if(nSyncFiles > 0)
    asprintf(&f, "restart-dat");
  else {
    fprintf(stderr,
        "ERROR: the number of sync-io files must be"
        "greater than or equal to zero\n");
    MPI_Abort(MPI_COMM_WORLD, 1);
    return NULL;
  }
  return f;
}
<|endoftext|>


<commit_before>/*-------------sierpinsky.cpp-------------------------------------------------//

 Purpose: This is a stand-alone file to draw the spherical cow logo

   Notes: Compile with
              g++ -L/path/to/GathVL -I/path/to/GathVL -lgathvl -o sierpinsky sierpinsky.cpp `pkg-config --cflags --libs cairo libavformat libavcodec libswresample libswscale libavutil` -Wl,-rpath,/path/to/GathVL

*-----------------------------------------------------------------------------*/

#include <iostream>
#include <random>
#include <gathvl/camera.h>
#include <gathvl/scene.h>

void sierpensky(camera& cam, scene& world, int n, int bin_size){
    color black = {0,0,0,1};
    color white = {1,1,1,1};
    color gray = {0.5,0.5,0.5,1};

    std::vector<vec> triangle_pts = {{0,0},{0.5,1},{1,0}};
    std::vector<std::shared_ptr<ellipse>> triangle(3);

    // Three tiangle points
    for (int i = 0; i < triangle.size(); ++i){
        vec loc = {world.size.x*0.5 - 400 + 800*triangle_pts[i].x,
                   world.size.y*0.5 + 400 - 800*triangle_pts[i].y};
        triangle[i] = std::make_shared<ellipse>(loc, vec{0,0}, 0, 1);
        triangle[i]->add_animator<vec_animator>(0+i*10,30+i*10,
                                                &triangle[i]->size,
                                                vec{0,0}, vec{5,5});
    }

    // Adding elements to world
    world.add_layer();
    world.add_layer();
    for (int i = 0; i < 3; ++i){
        world.add_object(triangle[i], 2);
    }

    // First, generate random point.

    vec pt = {rand() % 10000 * 0.0001, rand() % 10000 * 0.0001};

    //std::vector<std::share_ptr<ellipse>> balls;
    // Implementing Sierpinsky triangle
    for (int i = 0; i < n; ++i){
        double rnd = rand() % 10000 * 0.0001;
        if (rnd <= 0.33){
            pt = {0.5*(triangle_pts[0].x + pt.x),
                  0.5*(triangle_pts[0].y + pt.y)};
        }
        else if (rnd > 0.33 && rnd <= 0.66){
            pt = {0.5*(triangle_pts[1].x + pt.x),
                  0.5*(triangle_pts[1].y + pt.y)};
        }
        else{
            pt = {0.5*(triangle_pts[2].x + pt.x),
                  0.5*(triangle_pts[2].y + pt.y)};
        }

        if (i > 20){
            vec loc = {world.size.x*0.5 - 400 + 800*pt.x,
                       world.size.y*0.5 + 400 - 800*pt.y};

            color ball_color = {1-((double)n-i)/n,0,1-(double)i/n,1};
            auto ball = std::make_shared<ellipse>(ball_color,
                                                  loc, vec{0,0}, 0, 1);
            ball->add_animator<vec_animator>(30+floor(i/bin_size)-20,
                                             60+floor(i/bin_size)-20,
                                             &ball->size,
                                             vec{0,0}, vec{2,2});
            world.add_object(ball,1);
        }
    }

    for (int i = 0; i < 1200; ++i){
        world.update(i);
        cam.encode_frame(world);
    }

    world.clear();
}

int main(){

    camera cam(vec{1920, 1080});
    scene world = scene({1920, 1080}, {0, 0, 0, 1});

    cam.add_encoder<video_encoder>("/tmp/video.mp4", cam.size, 60);
    sierpensky(cam, world, 20000, 100);
    cam.clear_encoders();
}
<commit_msg>adding some trit enumeration<commit_after>/*-------------sierpinsky.cpp-------------------------------------------------//

 Purpose: This is a stand-alone file to draw the spherical cow logo

   Notes: Compile with
              g++ -L/path/to/GathVL -I/path/to/GathVL -lgathvl -o sierpinsky sierpinsky.cpp `pkg-config --cflags --libs cairo libavformat libavcodec libswresample libswscale libavutil` -Wl,-rpath,/path/to/GathVL

          Props to Kroppeb for help with incrementing trytes

*-----------------------------------------------------------------------------*/

#include <iostream>
#include <random>
#include <gathvl/camera.h>
#include <gathvl/scene.h>
#include <utility>

typedef unsigned long long ll;
typedef std::pair<ll, ll> tryte;

tryte increment(tryte number){
    ll inc = 1;
    while(inc){
        ll for2 = number.first & inc;
        ll overf = number.second & inc;
        number.first ^= inc ^ overf;
        number.second ^= for2 ^ overf;
        inc = overf << 1;
    }
    return number;
}

void print_tryte(tryte number, int trits){
    for(int i = 1 << (trits-1); i; i >>= 1){
        if(number.first & i){
            std::cout << "1";
        }else if(number.second & i){
            std::cout << "2";
        }else{
            std::cout << "0";
        }
    }
    std::cout << std::endl;
}

vec convert(tryte number, ll scale, vec B, vec C){
    return (number.first * B + number.second * C) / scale;
}

vec hutchinson(vec init, std::vector<vec> triangle, size_t i){

    vec out;
    switch(i){
        case 0:
            out = (init + triangle[i])/2.0;
            break;
        case 1:
            out = (init + triangle[i])/2.0;
            break;
        case 2:
            out = (init + triangle[i])/2.0;
            break;
    }

    return out;
}

void sierpinski_hutchinson(camera& cam, scene& world, int n, int bin_size){
    color black = {0,0,0,1};
    color white = {1,1,1,1};
    color gray = {0.5,0.5,0.5,1};

    tryte value (0,0);
    for(int i = 0; i < 3*3*3*3 ; i++){
        print_tryte(value,4);
        value = increment(value);
    }

    int size = 4;
    vec check = convert(value, (2 << (size -1 )), vec(0,1), vec(1,1));

    std::cout << check.x << '\t' << check.y << '\n';

    std::vector<vec> triangle_pts = {{0,0},{0.5,1},{1,0}};
    std::vector<std::shared_ptr<ellipse>> triangle(3);

    // Three triangle points
    for (int i = 0; i < triangle.size(); ++i){
        vec loc = {world.size.x*0.5 - 400 + 800*triangle_pts[i].x,
                   world.size.y*0.5 + 400 - 800*triangle_pts[i].y};
        triangle[i] = std::make_shared<ellipse>(loc, vec{0,0}, 0, 1);
        triangle[i]->add_animator<vec_animator>(0+i*10,30+i*10,
                                                &triangle[i]->size,
                                                vec{0,0}, vec{5,5});
    }

    // Adding elements to world
    world.add_layer();
    world.add_layer();
    for (int i = 0; i < 3; ++i){
        world.add_object(triangle[i], 2);
    }

    for (int i = 0; i < 100; ++i){
        world.update(i);
        cam.encode_frame(world);
    }

    world.clear();

}

void sierpinski_chaos(camera& cam, scene& world, int n, int bin_size){
    color black = {0,0,0,1};
    color white = {1,1,1,1};
    color gray = {0.5,0.5,0.5,1};

    std::vector<vec> triangle_pts = {{0,0},{0.5,1},{1,0}};
    std::vector<std::shared_ptr<ellipse>> triangle(3);

    // Three triangle points
    for (int i = 0; i < triangle.size(); ++i){
        vec loc = {world.size.x*0.5 - 400 + 800*triangle_pts[i].x,
                   world.size.y*0.5 + 400 - 800*triangle_pts[i].y};
        triangle[i] = std::make_shared<ellipse>(loc, vec{0,0}, 0, 1);
        triangle[i]->add_animator<vec_animator>(0+i*10,30+i*10,
                                                &triangle[i]->size,
                                                vec{0,0}, vec{5,5});
    }

    // Adding elements to world
    world.add_layer();
    world.add_layer();
    for (int i = 0; i < 3; ++i){
        world.add_object(triangle[i], 2);
    }

    // First, generate random point.

    vec pt = {rand() % 10000 * 0.0001, rand() % 10000 * 0.0001};

    //std::vector<std::share_ptr<ellipse>> balls;
    // Implementing Sierpinski triangle
    for (int i = 0; i < n; ++i){
        double rnd = rand() % 10000 * 0.0001;
        if (rnd <= 0.33){
            pt = {0.5*(triangle_pts[0].x + pt.x),
                  0.5*(triangle_pts[0].y + pt.y)};
        }
        else if (rnd > 0.33 && rnd <= 0.66){
            pt = {0.5*(triangle_pts[1].x + pt.x),
                  0.5*(triangle_pts[1].y + pt.y)};
        }
        else{
            pt = {0.5*(triangle_pts[2].x + pt.x),
                  0.5*(triangle_pts[2].y + pt.y)};
        }

        if (i > 20){
            vec loc = {world.size.x*0.5 - 400 + 800*pt.x,
                       world.size.y*0.5 + 400 - 800*pt.y};

            color ball_color = {1-((double)n-i)/n,0,1-(double)i/n,1};
            auto ball = std::make_shared<ellipse>(ball_color,
                                                  loc, vec{0,0}, 0, 1);
            ball->add_animator<vec_animator>(30+floor(i/bin_size)-20,
                                             60+floor(i/bin_size)-20,
                                             &ball->size,
                                             vec{0,0}, vec{2,2});
            world.add_object(ball,1);
        }
    }

    for (int i = 0; i < 1200; ++i){
        world.update(i);
        cam.encode_frame(world);
    }

    world.clear();
}

int main(){

    camera cam(vec{1920, 1080});
    scene world = scene({1920, 1080}, {0, 0, 0, 1});

    cam.add_encoder<video_encoder>("/tmp/video.mp4", cam.size, 60);
    sierpinski_hutchinson(cam, world, 20000, 100);
    //sierpinski_chaos(cam, world, 20000, 100);
    cam.clear_encoders();
}
<|endoftext|>


<commit_before><commit_msg>Update Ring For Android<commit_after><|endoftext|>


<commit_before>#pragma once

/*  libCppGUI - A GUI library for C++11/14

    Copyright 2016 Hans-Peter Gygax

    Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "./Widget.hpp"

namespace cppgui {

    // Main class declaration ---------------------------------------

    /** This macro definition must mirror the template class declaration that immediately follows.
     */
    #define CPPGUI_INSTANTIATE_MY_WIDGET(Config, With_layout) \
        template cppgui::My_widget<Config, With_layout>; \
        _CPPGUI_INSTANTIATE_MY_WIDGET(Config, With_layout);

    template<class Config>
    struct _my_widget
    {
        template<bool With_layout, class Parent> struct Layouter;

        // Main class declaration -----------------------------------

        #define _CPPGUI_INSTANTIATE_MY_WIDGET_BASE(Config, With_layout, ...) \
            template cppgui::_my_widget<Config>::Base<__VA_ARGS__, With_layout>; \
            template cppgui::_my_widget<Config>::Layouter<__VA_ARGS__, With_layout, \
                cppgui::Widget<Config, With_layout> >;

        /** The class is called "Base" because it is intended to be customized via template parameters.
         */
        template<bool With_layout>
        class Base:
            public Layouter<With_layout,            // Layouter aspect, parameterized with ...
                Widget<Config, With_layout> >       // ... the actual parent class: Widget<>
        {
        public:

            void init() override;

            void compute_view_from_data() override;

            void render(Canvas_t *, const Point &offset) override;
        };

        // Layouter aspect ----------------------------------------------

        /** This macro definition must mirror the layouter aspect class declaration.
            It should instantiate not just the Layouter aspect itself, but also any aspects it injects on
            its own (this example does not inject any, but see Label.hpp for an example).
         */
        #define _CPPGUI_INSTANTIATE_MY_WIDGET_LAYOUTER(Config, With_layout, ...) \
            template cppgui::_my_widget<Config>::Layouter<With_layout, __VA_ARGS__>; \
            template cppgui::Box__Layouter<Config, With_layout, __VA_ARGS__>;

        /** Dummy template specialization for when With_layout = false.
         */
        template<class Parent> struct Layouter<false, Parent>: public Parent {};

        /** "Real" layouter specialization that will be selected when With_layout = true.
         */
        template<class Parent>
        struct Layouter<true, Parent>: public
            Box__Layouter<Config, With_layout,
                Parent >
        {
            void init_layout() override;

            auto get_minimal_size() -> Extents override;

            void layout() override;

        protected:
            class My_widget_t: public Base<true> { friend struct Layouter; };

            /** Gives access to the main class, including protected and private sections.
            */
            auto p() { return static_cast<My_widget_t*>(this); }
        };

    }; // templated ns _my_widget

    // Specializations ----------------------------------------------

    #define CPPGUI_INSTANTIATE_MY_WIDGET(Config, With_layout) \
        template cppgui::My_widget<Config, With_layout>; \
        template cppgui::_my_widget<Config>; \
        _CPPGUI_INSTANTIATE_MY_WIDGET_BASE(Config, With_layout, cppgui::My_widget<Config, With_layout>);

    template<class Config, bool With_layout>
    class My_widget: public _my_widget<Config>::template Base<My_widget<Config, With_layout>, With_layout> { };

} // ns cppgui
<commit_msg>More polish to Widget_template<commit_after>#pragma once

/*  libCppGUI - A GUI library for C++11/14

    Copyright 2016 Hans-Peter Gygax

    Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "./Widget.hpp"

namespace cppgui {

    // Main class declaration ---------------------------------------

    template<class Config>
    struct _my_widget
    {
        template<bool With_layout, class Parent> struct Layouter;

        // Main class declaration -----------------------------------

        #define _CPPGUI_INSTANTIATE_MY_WIDGET_BASE(Config, With_layout, ...) \
            template cppgui::_my_widget<Config>::Base<__VA_ARGS__, With_layout>; \
            template cppgui::_my_widget<Config>::Layouter<__VA_ARGS__, With_layout, \
                cppgui::Widget<Config, With_layout> >;

        /** The class is called "Base" because it is intended to be customized via template parameters.
         */
        template<bool With_layout>
        class Base:
            public Layouter<With_layout,            // Layouter aspect, parameterized with ...
                Widget<Config, With_layout> >       // ... the actual parent class: Widget<>
        {
        public:

            void init() override;

            void compute_view_from_data() override;

            void render(Canvas_t *, const Point &offset) override;
        };

        // Layouter aspect ----------------------------------------------

        /** This macro definition must mirror the layouter aspect class declaration.
            It should instantiate not just all specializations of the Layouter aspect
            itself (meaning both the empty one for With_layout = false and the real one
            wgere With_layout = true), but also any aspects it injects on  its own
            (this example does not inject any, but see Label.hpp for an example).
         */
        #define _CPPGUI_INSTANTIATE_MY_WIDGET_LAYOUTER(Config, With_layout, ...) \
            template cppgui::_my_widget<Config>::Layouter<With_layout, __VA_ARGS__>; \
            template cppgui::Box__Layouter<Config, With_layout, __VA_ARGS__>;

        /** Dummy template specialization for when With_layout = false.
         */
        template<class Parent> struct Layouter<false, Parent>: public Parent {};

        /** "Real" layouter specialization that will be selected when With_layout = true.
         */
        template<class Parent>
        struct Layouter<true, Parent>: public
            Box__Layouter<Config, With_layout,
                Parent >
        {
            void init_layout() override;

            auto get_minimal_size() -> Extents override;

            void layout() override;

        protected:
            class My_widget_t: public Base<true> { friend struct Layouter; };

            /** Gives access to the main class, including protected and private sections.
            */
            auto p() { return static_cast<My_widget_t*>(this); }
        };

    }; // templated ns _my_widget

    // Export section -----------------------------------------------

    /** RECIPE:

        This is where you export your widget class template into the cppgui namespace,
        under a meaningful name.

        An instantion macro must be provided for every templated widget type.
        Do not forget to add a call to this macro to the CPPGUI_INSTANTIATE_ALL_WIDGETS()
        macro in `all_widgets.hpp`.
     */

    #define CPPGUI_INSTANTIATE_MY_WIDGET(Config, With_layout) \
        template cppgui::My_widget<Config, With_layout>; \
        template cppgui::_my_widget<Config>; \
        _CPPGUI_INSTANTIATE_MY_WIDGET_BASE(Config, With_layout, cppgui::My_widget<Config, With_layout>);

    template<class Config, bool With_layout>
    class My_widget: public _my_widget<Config>::template Base<My_widget<Config, With_layout>, With_layout> { };

} // ns cppgui
<|endoftext|>


<commit_before>/*
  Copyright 2011 Larry Gritz and the other authors and contributors.
  All Rights Reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  * Redistributions 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.
  * Neither the name of the software's owners nor the names of its
    contributors may 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 COPYRIGHT
  OWNER 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.

  (This is the Modified BSD License)
*/

/// \file
/// Implementation of ImageBufAlgo algorithms related to OpenCV.
/// These are nonfunctional if OpenCV is not found at build time.

#ifdef USE_OPENCV
#include <opencv2/core/core_c.h>
#include <opencv2/highgui/highgui_c.h>
#endif

#include <iostream>
#include <map>

#include "imagebuf.h"
#include "imagebufalgo.h"
#include "dassert.h"
#include "thread.h"

OIIO_NAMESPACE_ENTER
{

bool
ImageBufAlgo::from_IplImage (ImageBuf &dst, const IplImage *ipl,
                             TypeDesc convert)
{
    if (! ipl) {
        DASSERT (0 && "ImageBufAlgo::fromIplImage called with NULL ipl");
        return false;
    }
#ifdef USE_OPENCV
    TypeDesc srcformat;
    switch (ipl->depth) {
    case IPL_DEPTH_8U :
        srcformat = TypeDesc::UINT8;  break;
    case IPL_DEPTH_8S :
        srcformat = TypeDesc::INT8;  break;
    case IPL_DEPTH_16U :
        srcformat = TypeDesc::UINT16;  break;
    case IPL_DEPTH_16S :
        srcformat = TypeDesc::INT16;  break;
    case IPL_DEPTH_32F :
        srcformat = TypeDesc::FLOAT;  break;
    case IPL_DEPTH_64F :
        srcformat = TypeDesc::DOUBLE;  break;
    default:
        DASSERT (0 && "unknown IplImage type");
        return false;
    }

    TypeDesc dstformat = (convert != TypeDesc::UNKNOWN) ? convert : srcformat;
    ImageSpec spec (ipl->width, ipl->height, ipl->nChannels, dstformat);
    // N.B. The OpenCV headers say that ipl->alphaChannel,
    // ipl->colorModel, and ipl->channelSeq are ignored by OpenCV.

    if (ipl->dataOrder != IPL_DATA_ORDER_PIXEL) {
        // We don't handle separate color channels, and OpenCV doesn't either
        return false;
    }

    dst.reset (dst.name(), spec);
    size_t pixelsize = srcformat.size()*spec.nchannels;
    // Account for the origin in the line step size, to end up with the
    // standard OIIO origin-at-upper-left:
    size_t linestep = ipl->origin ? -ipl->widthStep : ipl->widthStep;
    // Block copy and convert
    convert_image (spec.nchannels, spec.width, spec.height, 1,
                   ipl->imageData, srcformat,
                   pixelsize, linestep, 0,
                   dst.pixeladdr(0,0), dstformat,
                   spec.pixel_bytes(), spec.scanline_bytes(), 0);
    // FIXME - honor dataOrder.  I'm not sure if it is ever used by
    // OpenCV.  Fix when it becomes a problem.

    // OpenCV uses BGR ordering
    // FIXME: what do they do with alpha?
    if (spec.nchannels >= 3) {
        float pixel[4];
        for (int y = 0;  y < spec.height;  ++y) {
            for (int x = 0;  x < spec.width;  ++x) {
                dst.getpixel (x, y, pixel, 4);
                float tmp = pixel[0];  pixel[0] = pixel[2]; pixel[2] = tmp;
                dst.setpixel (x, y, pixel, 4);
            }
        }
    }
    // FIXME -- the copy and channel swap should happen all as one loop,
    // probably templated by type.

    return true;
#else
    return false;
#endif
}

IplImage *
ImageBufAlgo::to_IplImage (const ImageBuf &src)
{
#ifdef USE_OPENCV
    return NULL;
#else
    return NULL;
#endif
}

namespace {

static mutex opencv_mutex;

#ifdef USE_OPENCV
class CameraHolder {
public:
    CameraHolder () { }
    // Destructor frees all cameras
    ~CameraHolder () {
        for (camera_map::iterator i = m_cvcaps.begin();  i != m_cvcaps.end();  ++i)
            cvReleaseCapture (&(i->second));
    }
    // Get the capture device, creating a new one if necessary.
    CvCapture * operator[] (int cameranum) {
        camera_map::iterator i = m_cvcaps.find (cameranum);
        if (i != m_cvcaps.end())
            return i->second;
        CvCapture *cvcam = cvCreateCameraCapture (cameranum);
        m_cvcaps[cameranum] = cvcam;
        return cvcam;
    }
private:
    typedef std::map<int,CvCapture*> camera_map;
    camera_map m_cvcaps;
};

static CameraHolder cameras;
#endif

};

bool
ImageBufAlgo::capture_image (ImageBuf &dst, int cameranum, TypeDesc convert)
{
#ifdef USE_OPENCV
    IplImage *frame = NULL;
    {
        // This block is mutex-protected
        lock_guard lock (opencv_mutex);
        CvCapture *cvcam = cameras[cameranum];
        if (! cvcam) {
            return false;  // failed somehow
        }
        frame = cvQueryFrame (cvcam);
        if (! frame) {
            return false;  // failed somehow
        }
    }
    bool ok = ImageBufAlgo::from_IplImage (dst, frame, convert);
    // cvReleaseImage (&frame);   // unnecessary?
    return ok;
#else
    return false;
#endif
}

}
OIIO_NAMESPACE_EXIT
<commit_msg>Have ImageBufAlgo::capture_image put the capture date/time in the metadata.<commit_after>/*
  Copyright 2011 Larry Gritz and the other authors and contributors.
  All Rights Reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  * Redistributions 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.
  * Neither the name of the software's owners nor the names of its
    contributors may 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 COPYRIGHT
  OWNER 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.

  (This is the Modified BSD License)
*/

/// \file
/// Implementation of ImageBufAlgo algorithms related to OpenCV.
/// These are nonfunctional if OpenCV is not found at build time.

#ifdef USE_OPENCV
#include <opencv2/core/core_c.h>
#include <opencv2/highgui/highgui_c.h>
#endif

#include <iostream>
#include <map>

#include "imagebuf.h"
#include "imagebufalgo.h"
#include "dassert.h"
#include "thread.h"
#include "sysutil.h"

OIIO_NAMESPACE_ENTER
{

bool
ImageBufAlgo::from_IplImage (ImageBuf &dst, const IplImage *ipl,
                             TypeDesc convert)
{
    if (! ipl) {
        DASSERT (0 && "ImageBufAlgo::fromIplImage called with NULL ipl");
        return false;
    }
#ifdef USE_OPENCV
    TypeDesc srcformat;
    switch (ipl->depth) {
    case IPL_DEPTH_8U :
        srcformat = TypeDesc::UINT8;  break;
    case IPL_DEPTH_8S :
        srcformat = TypeDesc::INT8;  break;
    case IPL_DEPTH_16U :
        srcformat = TypeDesc::UINT16;  break;
    case IPL_DEPTH_16S :
        srcformat = TypeDesc::INT16;  break;
    case IPL_DEPTH_32F :
        srcformat = TypeDesc::FLOAT;  break;
    case IPL_DEPTH_64F :
        srcformat = TypeDesc::DOUBLE;  break;
    default:
        DASSERT (0 && "unknown IplImage type");
        return false;
    }

    TypeDesc dstformat = (convert != TypeDesc::UNKNOWN) ? convert : srcformat;
    ImageSpec spec (ipl->width, ipl->height, ipl->nChannels, dstformat);
    // N.B. The OpenCV headers say that ipl->alphaChannel,
    // ipl->colorModel, and ipl->channelSeq are ignored by OpenCV.

    if (ipl->dataOrder != IPL_DATA_ORDER_PIXEL) {
        // We don't handle separate color channels, and OpenCV doesn't either
        return false;
    }

    dst.reset (dst.name(), spec);
    size_t pixelsize = srcformat.size()*spec.nchannels;
    // Account for the origin in the line step size, to end up with the
    // standard OIIO origin-at-upper-left:
    size_t linestep = ipl->origin ? -ipl->widthStep : ipl->widthStep;
    // Block copy and convert
    convert_image (spec.nchannels, spec.width, spec.height, 1,
                   ipl->imageData, srcformat,
                   pixelsize, linestep, 0,
                   dst.pixeladdr(0,0), dstformat,
                   spec.pixel_bytes(), spec.scanline_bytes(), 0);
    // FIXME - honor dataOrder.  I'm not sure if it is ever used by
    // OpenCV.  Fix when it becomes a problem.

    // OpenCV uses BGR ordering
    // FIXME: what do they do with alpha?
    if (spec.nchannels >= 3) {
        float pixel[4];
        for (int y = 0;  y < spec.height;  ++y) {
            for (int x = 0;  x < spec.width;  ++x) {
                dst.getpixel (x, y, pixel, 4);
                float tmp = pixel[0];  pixel[0] = pixel[2]; pixel[2] = tmp;
                dst.setpixel (x, y, pixel, 4);
            }
        }
    }
    // FIXME -- the copy and channel swap should happen all as one loop,
    // probably templated by type.

    return true;
#else
    return false;
#endif
}

IplImage *
ImageBufAlgo::to_IplImage (const ImageBuf &src)
{
#ifdef USE_OPENCV
    return NULL;
#else
    return NULL;
#endif
}

namespace {

static mutex opencv_mutex;

#ifdef USE_OPENCV
class CameraHolder {
public:
    CameraHolder () { }
    // Destructor frees all cameras
    ~CameraHolder () {
        for (camera_map::iterator i = m_cvcaps.begin();  i != m_cvcaps.end();  ++i)
            cvReleaseCapture (&(i->second));
    }
    // Get the capture device, creating a new one if necessary.
    CvCapture * operator[] (int cameranum) {
        camera_map::iterator i = m_cvcaps.find (cameranum);
        if (i != m_cvcaps.end())
            return i->second;
        CvCapture *cvcam = cvCreateCameraCapture (cameranum);
        m_cvcaps[cameranum] = cvcam;
        return cvcam;
    }
private:
    typedef std::map<int,CvCapture*> camera_map;
    camera_map m_cvcaps;
};

static CameraHolder cameras;
#endif

};

bool
ImageBufAlgo::capture_image (ImageBuf &dst, int cameranum, TypeDesc convert)
{
#ifdef USE_OPENCV
    IplImage *frame = NULL;
    {
        // This block is mutex-protected
        lock_guard lock (opencv_mutex);
        CvCapture *cvcam = cameras[cameranum];
        if (! cvcam) {
            return false;  // failed somehow
        }
        frame = cvQueryFrame (cvcam);
        if (! frame) {
            return false;  // failed somehow
        }
    }

    time_t now;
    time (&now);
    struct tm tmtime;
    Sysutil::get_local_time (&now, &tmtime);
    std::string datetime = Strutil::format ("%4d:%02d:%02d %02d:%02d:%02d",
                                   tmtime.tm_year+1900, tmtime.tm_mon+1,
                                   tmtime.tm_mday, tmtime.tm_hour,
                                   tmtime.tm_min, tmtime.tm_sec);

    bool ok = ImageBufAlgo::from_IplImage (dst, frame, convert);
    // cvReleaseImage (&frame);   // unnecessary?
    if (ok)
        dst.specmod().attribute ("DateTime", datetime);

    return ok;
#else
    return false;
#endif
}

}
OIIO_NAMESPACE_EXIT
<|endoftext|>