<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the FOO module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qticonloader.h"
#include <QtGui/QPixmapCache>

#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtCore/QString>
#include <QtCore/QLibrary>
#include <QtCore/QSettings>
#include <QtCore/QTextStream>

#ifdef Q_WS_X11

class QIconTheme
{
public:
    QIconTheme(QHash <int, QString> dirList, QStringList parents) :
            _dirList(dirList), _parents(parents), _valid(true){ }
    QIconTheme() : _valid(false){ }
    QHash <int, QString> dirList() {return _dirList;}
    QStringList parents() {return _parents;}
    bool isValid() {return _valid;}

private:
    QHash <int, QString> _dirList;
    QStringList _parents;
    bool _valid;
};

class QtIconLoaderImplementation
{
public:
    QtIconLoaderImplementation();
    QString findIcon(int size, const QString &name) const;

private:
    QIconTheme parseIndexFile(const QString &themeName) const;
    void lookupIconTheme() const;
    QString findIconHelper(int size,
                           const QString &themeName,
                           const QString &iconName,
                           QStringList &visited) const;
    mutable QString themeName;
    mutable QStringList iconDirs;
    mutable QHash <QString, QIconTheme> themeList;
};

Q_GLOBAL_STATIC(QtIconLoaderImplementation, iconLoaderInstance)
#endif

/*!

    Returns the standard icon for the given icon /a name
    as specified in the freedesktop icon spec
    http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html

    /a fallback is an optional argument to specify the icon to be used if
    no icon is found on the platform. This is particularily useful for
    crossplatform code.

*/
QString QtIconLoader::icon(const QString &name)
{
    // fast path: check if it exists as-is
    if (QFile::exists(name))
        return name;
#ifdef Q_WS_X11
    QString pngExtension(QLatin1String(".png"));
    QList<int> iconSizes;
    iconSizes << 64 << 48 << 32 << 24 << 16;
    Q_FOREACH (int size, iconSizes) {
        QString path = iconLoaderInstance()->findIcon(size, name + pngExtension);
        if (!path.isEmpty())
            return path;
    }
#endif
    Q_UNUSED(name);
    return QString();
}

#ifdef Q_WS_X11

QtIconLoaderImplementation::QtIconLoaderImplementation()
{
    lookupIconTheme();
}

extern "C" {
    struct GConfClient;
    struct GError;
    typedef void (*Ptr_g_type_init)();
    typedef GConfClient* (*Ptr_gconf_client_get_default)();
    typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **);
    typedef void (*Ptr_g_object_unref)(void *);
    typedef void (*Ptr_g_free)(void*);
    static Ptr_g_type_init p_g_type_init = 0;
    static Ptr_gconf_client_get_default p_gconf_client_get_default = 0;
    static Ptr_gconf_client_get_string p_gconf_client_get_string = 0;
    static Ptr_g_object_unref p_g_object_unref = 0;
    static Ptr_g_free p_g_free = 0;
}

static int kdeVersion()
{
    static int version = qgetenv("KDE_SESSION_VERSION").toInt();
    return version;
}

static QString kdeHome()
{
    static QString kdeHomePath;
    if (kdeHomePath.isEmpty()) {
        kdeHomePath = QFile::decodeName(qgetenv("KDEHOME"));
        if (kdeHomePath.isEmpty()) {
            int kdeSessionVersion = kdeVersion();
            QDir homeDir(QDir::homePath());
            QString kdeConfDir(QLatin1String("/.kde"));
            if (4 == kdeSessionVersion && homeDir.exists(QLatin1String(".kde4")))
                kdeConfDir = QLatin1String("/.kde4");
            kdeHomePath = QDir::homePath() + kdeConfDir;
        }
    }
    return kdeHomePath;
}

void QtIconLoaderImplementation::lookupIconTheme() const
{

#ifdef Q_WS_X11
    QString dataDirs = QFile::decodeName(getenv("XDG_DATA_DIRS"));
    if (dataDirs.isEmpty())
        dataDirs = QLatin1String("/usr/local/share/:/usr/share/");

    dataDirs.prepend(QDir::homePath() + QLatin1String("/:"));
    iconDirs = dataDirs.split(QLatin1Char(':'));

    // If we are running GNOME we resolve and use GConf. In all other
    // cases we currently use the KDE icon theme

    if (qgetenv("DESKTOP_SESSION") == "gnome" ||
        !qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {

        if (themeName.isEmpty()) {
            // Resolve glib and gconf

            p_g_type_init =              (Ptr_g_type_init)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_type_init");
            p_gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_default");
            p_gconf_client_get_string =  (Ptr_gconf_client_get_string)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_string");
            p_g_object_unref =           (Ptr_g_object_unref)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_object_unref");
            p_g_free =                   (Ptr_g_free)QLibrary::resolve(QLatin1String("glib-2.0"), 0, "g_free");

            if (p_g_type_init && p_gconf_client_get_default &&
                p_gconf_client_get_string && p_g_object_unref &&
                p_g_free) {

                p_g_type_init();
                GConfClient* client = p_gconf_client_get_default();

                // try meego first, since our 'default' target is meego
                char *str = p_gconf_client_get_string(client, "/meegotouch/theme/name", 0);
                if (str) {
                    themeName = QString::fromUtf8(str);
                        qDebug() << Q_FUNC_INFO << "Picked theme name from MeeGo key: " << themeName;
                } else {
                    // default gnome case
                    str = p_gconf_client_get_string(client, "/desktop/gnome/interface/icon_theme", 0);
                    if (str) {
                        themeName = QString::fromUtf8(str);
                        qDebug() << Q_FUNC_INFO << "Picked theme name from gnome key: " << themeName;
                    } else {
                        themeName = QString();
                    }
                }

                p_g_free(str);
                p_g_object_unref(client);
            }

            if (themeName.isEmpty()) {
                qDebug() << Q_FUNC_INFO << "Defaulted to 'gnome'";
                themeName = QLatin1String("gnome");
            }
        }

        if (!themeName.isEmpty())
            return;
    }

    // KDE (and others)
    if (dataDirs.isEmpty())
        dataDirs = QLatin1String("/usr/local/share/:/usr/share/");

    dataDirs += QLatin1Char(':') + kdeHome() + QLatin1String("/share");
    dataDirs.prepend(QDir::homePath() + QLatin1String("/:"));
    QStringList kdeDirs = QFile::decodeName(getenv("KDEDIRS")).split(QLatin1Char(':'));
    Q_FOREACH (const QString dirName, kdeDirs)
        dataDirs.append(QLatin1Char(':') + dirName + QLatin1String("/share"));
    iconDirs = dataDirs.split(QLatin1Char(':'));

    QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde"));
    QDir dir(fileInfo.canonicalFilePath());
    QString kdeDefault = kdeVersion() >= 4 ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg");
    QString defaultTheme = fileInfo.exists() ? dir.dirName() : kdeDefault;
    QSettings settings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
    settings.beginGroup(QLatin1String("Icons"));
    themeName = settings.value(QLatin1String("Theme"), defaultTheme).toString();
#endif
    qDebug() << Q_FUNC_INFO << "Decided an icon theme of " << themeName;
}

QIconTheme QtIconLoaderImplementation::parseIndexFile(const QString &themeName) const
{
    QIconTheme theme;
    QFile themeIndex;
    QStringList parents;
    QHash <int, QString> dirList;

    for ( int i = 0 ; i < iconDirs.size() && !themeIndex.exists() ; ++i) {
        const QString &contentDir = QLatin1String(iconDirs[i].startsWith(QDir::homePath()) ? "/.icons/" : "/icons/");
        themeIndex.setFileName(iconDirs[i] + contentDir + themeName + QLatin1String("/index.theme"));
    }

    if (themeIndex.exists()) {
        QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
        Q_FOREACH (const QString &key, indexReader.allKeys()) {
            if (key.endsWith("/Size")) {
                if (int size = indexReader.value(key).toInt())
                    dirList.insertMulti(size, key.left(key.size() - 5));
            }
        }

        // Parent themes provide fallbacks for missing icons
        parents = indexReader.value(QLatin1String("Icon Theme/Inherits")).toStringList();
    }

    if (kdeVersion() >= 3) {
        QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde"));
        QDir dir(fileInfo.canonicalFilePath());
        QString defaultKDETheme = dir.exists() ? dir.dirName() : kdeVersion() == 3 ?
                                  QString::fromLatin1("crystalsvg") : QString::fromLatin1("oxygen");
        if (!parents.contains(defaultKDETheme) && themeName != defaultKDETheme)
            parents.append(defaultKDETheme);
    } else if (parents.isEmpty() && themeName != QLatin1String("hicolor")) {
        parents.append(QLatin1String("hicolor"));
    }

    theme = QIconTheme(dirList, parents);
    return theme;
}

QString QtIconLoaderImplementation::findIconHelper(int size, const QString &themeName,
                                                   const QString &iconName, QStringList &visited) const
{
    if (!themeName.isEmpty()) {
        visited << themeName;
        QIconTheme theme = themeList.value(themeName);

        if (!theme.isValid()) {
            theme = parseIndexFile(themeName);
            themeList.insert(themeName, theme);
        }

        if (!theme.isValid())
            return QString();

        QList <QString> subDirs = theme.dirList().values(size);
        QPixmap pixmap;

        for ( int i = 0 ; i < iconDirs.size() ; ++i) {
            for ( int j = 0 ; j < subDirs.size() ; ++j) {
                QString contentDir = (iconDirs[i].startsWith(QDir::homePath())) ?
                                     QLatin1String("/.icons/") : QLatin1String("/icons/");
                QString fileName = iconDirs[i] + contentDir + themeName + QLatin1Char('/') + subDirs[j] + QLatin1Char('/') + iconName;
                QFile file(fileName);
                pixmap = QPixmap(fileName);
                if (!pixmap.isNull())
                    return fileName;
            }
        }

        if (pixmap.isNull()) {
            QStringList parents = theme.parents();
            QString retval;
            //search recursively through inherited themes
            for (int i = 0 ; retval.isNull() && i < parents.size() ; ++i) {
                QString parentTheme = parents[i].trimmed();
                if (!visited.contains(parentTheme)) //guard against endless recursion
                    retval = findIconHelper(size, parentTheme, iconName, visited);
            }

            return retval;
        }
    }
    return QString();
}

QString QtIconLoaderImplementation::findIcon(int size, const QString &name) const
{
    if (!themeName.isEmpty()) {
        QStringList visited;
        return findIconHelper(size, themeName, name, visited);
    }
    return QString("???");
}
#endif //Q_WS_X11
<commit_msg>another crack at fixing icons<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the FOO module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qticonloader.h"
#include <QtGui/QPixmapCache>

#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtCore/QString>
#include <QtCore/QLibrary>
#include <QtCore/QSettings>
#include <QtCore/QTextStream>

#ifdef Q_WS_X11

class QIconTheme
{
public:
    QIconTheme(QHash <int, QString> dirList, QStringList parents) :
            _dirList(dirList), _parents(parents), _valid(true){ }
    QIconTheme() : _valid(false){ }
    QHash <int, QString> dirList() {return _dirList;}
    QStringList parents() {return _parents;}
    bool isValid() {return _valid;}

private:
    QHash <int, QString> _dirList;
    QStringList _parents;
    bool _valid;
};

class QtIconLoaderImplementation
{
public:
    QtIconLoaderImplementation();
    QString findIcon(int size, const QString &name) const;

private:
    QIconTheme parseIndexFile(const QString &themeName) const;
    void lookupIconTheme() const;
    QString findIconHelper(int size,
                           const QString &themeName,
                           const QString &iconName,
                           QStringList &visited) const;
    mutable QString themeName;
    mutable QStringList iconDirs;
    mutable QHash <QString, QIconTheme> themeList;
};

Q_GLOBAL_STATIC(QtIconLoaderImplementation, iconLoaderInstance)
#endif

/*!

    Returns the standard icon for the given icon /a name
    as specified in the freedesktop icon spec
    http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html

    /a fallback is an optional argument to specify the icon to be used if
    no icon is found on the platform. This is particularily useful for
    crossplatform code.

*/
QString QtIconLoader::icon(const QString &name)
{
    // fast path: check if it exists as-is
    if (QFile::exists(name))
        return name;
#ifdef Q_WS_X11
    QString pngExtension(QLatin1String(".png"));
    QList<int> iconSizes;
    iconSizes << 64 << 48 << 32 << 24 << 16;
    Q_FOREACH (int size, iconSizes) {
        QString path = iconLoaderInstance()->findIcon(size, name + pngExtension);
        if (!path.isEmpty())
            return path;
    }
#endif
    Q_UNUSED(name);
    return QString();
}

#ifdef Q_WS_X11

QtIconLoaderImplementation::QtIconLoaderImplementation()
{
    lookupIconTheme();
}

extern "C" {
    struct GConfClient;
    struct GError;
    typedef void (*Ptr_g_type_init)();
    typedef GConfClient* (*Ptr_gconf_client_get_default)();
    typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **);
    typedef void (*Ptr_g_object_unref)(void *);
    typedef void (*Ptr_g_free)(void*);
    static Ptr_g_type_init p_g_type_init = 0;
    static Ptr_gconf_client_get_default p_gconf_client_get_default = 0;
    static Ptr_gconf_client_get_string p_gconf_client_get_string = 0;
    static Ptr_g_object_unref p_g_object_unref = 0;
    static Ptr_g_free p_g_free = 0;
}

static int kdeVersion()
{
    static int version = qgetenv("KDE_SESSION_VERSION").toInt();
    return version;
}

static QString kdeHome()
{
    static QString kdeHomePath;
    if (kdeHomePath.isEmpty()) {
        kdeHomePath = QFile::decodeName(qgetenv("KDEHOME"));
        if (kdeHomePath.isEmpty()) {
            int kdeSessionVersion = kdeVersion();
            QDir homeDir(QDir::homePath());
            QString kdeConfDir(QLatin1String("/.kde"));
            if (4 == kdeSessionVersion && homeDir.exists(QLatin1String(".kde4")))
                kdeConfDir = QLatin1String("/.kde4");
            kdeHomePath = QDir::homePath() + kdeConfDir;
        }
    }
    return kdeHomePath;
}

void QtIconLoaderImplementation::lookupIconTheme() const
{

#ifdef Q_WS_X11
    QString dataDirs = QFile::decodeName(getenv("XDG_DATA_DIRS"));
    if (dataDirs.isEmpty())
        dataDirs = QLatin1String("/usr/local/share/:/usr/share/");

    dataDirs.prepend(QDir::homePath() + QLatin1String("/:"));
    iconDirs = dataDirs.split(QLatin1Char(':'));

    if (!themeName.isEmpty())
        return;

    // If we are running GNOME we resolve and use GConf. In all other
    // cases we currently use the KDE icon theme
    // Resolve glib and gconf
    p_g_type_init =              (Ptr_g_type_init)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_type_init");
    p_gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_default");
    p_gconf_client_get_string =  (Ptr_gconf_client_get_string)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_string");
    p_g_object_unref =           (Ptr_g_object_unref)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_object_unref");
    p_g_free =                   (Ptr_g_free)QLibrary::resolve(QLatin1String("glib-2.0"), 0, "g_free");

    if (p_g_type_init && p_gconf_client_get_default &&
        p_gconf_client_get_string && p_g_object_unref &&
        p_g_free) {

        p_g_type_init();
        GConfClient* client = p_gconf_client_get_default();

        // try meego first, since our 'default' target is meego
        char *str = p_gconf_client_get_string(client, "/meegotouch/theme/name", 0);
        if (str) {
            themeName = QString::fromUtf8(str);
                qDebug() << Q_FUNC_INFO << "Picked theme name from MeeGo key: " << themeName;
        } else {
            // default gnome case
            str = p_gconf_client_get_string(client, "/desktop/gnome/interface/icon_theme", 0);
            if (str) {
                themeName = QString::fromUtf8(str);
                qDebug() << Q_FUNC_INFO << "Picked theme name from gnome key: " << themeName;
            } else {
                themeName = QString();
            }
        }

        p_g_free(str);
        p_g_object_unref(client);
    }

    // TODO: should we default to something?

    // KDE (and others)
    if (dataDirs.isEmpty())
        dataDirs = QLatin1String("/usr/local/share/:/usr/share/");

    dataDirs += QLatin1Char(':') + kdeHome() + QLatin1String("/share");
    dataDirs.prepend(QDir::homePath() + QLatin1String("/:"));
    QStringList kdeDirs = QFile::decodeName(getenv("KDEDIRS")).split(QLatin1Char(':'));
    Q_FOREACH (const QString dirName, kdeDirs)
        dataDirs.append(QLatin1Char(':') + dirName + QLatin1String("/share"));
    iconDirs = dataDirs.split(QLatin1Char(':'));

    QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde"));
    QDir dir(fileInfo.canonicalFilePath());
    QString kdeDefault = kdeVersion() >= 4 ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg");
    QString defaultTheme = fileInfo.exists() ? dir.dirName() : kdeDefault;
    QSettings settings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
    settings.beginGroup(QLatin1String("Icons"));
    themeName = settings.value(QLatin1String("Theme"), defaultTheme).toString();
#endif
    qDebug() << Q_FUNC_INFO << "Decided an icon theme of " << themeName;
}

QIconTheme QtIconLoaderImplementation::parseIndexFile(const QString &themeName) const
{
    QIconTheme theme;
    QFile themeIndex;
    QStringList parents;
    QHash <int, QString> dirList;

    for ( int i = 0 ; i < iconDirs.size() && !themeIndex.exists() ; ++i) {
        const QString &contentDir = QLatin1String(iconDirs[i].startsWith(QDir::homePath()) ? "/.icons/" : "/icons/");
        themeIndex.setFileName(iconDirs[i] + contentDir + themeName + QLatin1String("/index.theme"));
    }

    if (themeIndex.exists()) {
        QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
        Q_FOREACH (const QString &key, indexReader.allKeys()) {
            if (key.endsWith("/Size")) {
                if (int size = indexReader.value(key).toInt())
                    dirList.insertMulti(size, key.left(key.size() - 5));
            }
        }

        // Parent themes provide fallbacks for missing icons
        parents = indexReader.value(QLatin1String("Icon Theme/Inherits")).toStringList();
    }

    if (kdeVersion() >= 3) {
        QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde"));
        QDir dir(fileInfo.canonicalFilePath());
        QString defaultKDETheme = dir.exists() ? dir.dirName() : kdeVersion() == 3 ?
                                  QString::fromLatin1("crystalsvg") : QString::fromLatin1("oxygen");
        if (!parents.contains(defaultKDETheme) && themeName != defaultKDETheme)
            parents.append(defaultKDETheme);
    } else if (parents.isEmpty() && themeName != QLatin1String("hicolor")) {
        parents.append(QLatin1String("hicolor"));
    }

    theme = QIconTheme(dirList, parents);
    return theme;
}

QString QtIconLoaderImplementation::findIconHelper(int size, const QString &themeName,
                                                   const QString &iconName, QStringList &visited) const
{
    if (!themeName.isEmpty()) {
        visited << themeName;
        QIconTheme theme = themeList.value(themeName);

        if (!theme.isValid()) {
            theme = parseIndexFile(themeName);
            themeList.insert(themeName, theme);
        }

        if (!theme.isValid())
            return QString();

        QList <QString> subDirs = theme.dirList().values(size);
        QPixmap pixmap;

        for ( int i = 0 ; i < iconDirs.size() ; ++i) {
            for ( int j = 0 ; j < subDirs.size() ; ++j) {
                QString contentDir = (iconDirs[i].startsWith(QDir::homePath())) ?
                                     QLatin1String("/.icons/") : QLatin1String("/icons/");
                QString fileName = iconDirs[i] + contentDir + themeName + QLatin1Char('/') + subDirs[j] + QLatin1Char('/') + iconName;
                QFile file(fileName);
                pixmap = QPixmap(fileName);
                if (!pixmap.isNull())
                    return fileName;
            }
        }

        if (pixmap.isNull()) {
            QStringList parents = theme.parents();
            QString retval;
            //search recursively through inherited themes
            for (int i = 0 ; retval.isNull() && i < parents.size() ; ++i) {
                QString parentTheme = parents[i].trimmed();
                if (!visited.contains(parentTheme)) //guard against endless recursion
                    retval = findIconHelper(size, parentTheme, iconName, visited);
            }

            return retval;
        }
    }
    return QString();
}

QString QtIconLoaderImplementation::findIcon(int size, const QString &name) const
{
    if (!themeName.isEmpty()) {
        QStringList visited;
        return findIconHelper(size, themeName, name, visited);
    }
    return QString("???");
}
#endif //Q_WS_X11
<|endoftext|>


<commit_before><commit_msg>Changed ties in quantile method<commit_after><|endoftext|>


<commit_before>#ifndef STAN_MATH_FWD_META_HPP
#define STAN_MATH_FWD_META_HPP

#include <stan/math/fwd/scal/meta/is_fvar.hpp>
#include <stan/math/fwd/scal/meta/partials_type.hpp>
#include <stan/math/fwd/mat/meta/operands_and_partials.hpp>

#include <stan/math/fwd/scal/meta/ad_promotable.hpp>
#include <stan/math/fwd/scal/meta/operands_and_partials.hpp>

#endif
<commit_msg>reorder meta<commit_after>#ifndef STAN_MATH_FWD_META_HPP
#define STAN_MATH_FWD_META_HPP

#include <stan/math/fwd/scal/meta/ad_promotable.hpp>
#include <stan/math/fwd/scal/meta/is_fvar.hpp>
#include <stan/math/fwd/scal/meta/partials_type.hpp>
#include <stan/math/fwd/scal/meta/operands_and_partials.hpp>
#include <stan/math/fwd/mat/meta/operands_and_partials.hpp>

#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_SCAL_FUN_GAMMA_P_HPP
#define STAN_MATH_REV_SCAL_FUN_GAMMA_P_HPP

#include <stan/math/rev/core.hpp>
#include <stan/math/prim/scal/fun/is_inf.hpp>
#include <stan/math/prim/scal/err/domain_error.hpp>
#include <stan/math/prim/scal/fun/digamma.hpp>
#include <stan/math/prim/scal/fun/gamma_p.hpp>
#include <stan/math/prim/scal/fun/lgamma.hpp>
#include <stan/math/prim/scal/fun/grad_reg_lower_inc_gamma.hpp>
#include <valarray>
#include <limits>

namespace stan {
namespace math {

namespace {
class gamma_p_vv_vari : public op_vv_vari {
 public:
  gamma_p_vv_vari(vari* avi, vari* bvi)
      : op_vv_vari(gamma_p(avi->val_, bvi->val_), avi, bvi) {}
  void chain() {
    using boost::math::lgamma;
    using std::exp;
    using std::fabs;
    using std::log;

    if (is_inf(avi_->val_)) {
      avi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      bvi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }
    if (is_inf(bvi_->val_)) {
      avi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      bvi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }

    // return zero derivative as gamma_p is flat
    // to machine precision for b / a > 10
    if (std::fabs(bvi_->val_ / avi_->val_) > 10)
      return;

    avi_->adj_
        += adj_ * grad_reg_lower_inc_gamma(avi_->val_, bvi_->val_, 1.0e-10);
    bvi_->adj_ += adj_
                  * exp(-bvi_->val_ + (avi_->val_ - 1.0) * log(bvi_->val_)
                        - lgamma(avi_->val_));
  }
};

class gamma_p_vd_vari : public op_vd_vari {
 public:
  gamma_p_vd_vari(vari* avi, double b)
      : op_vd_vari(gamma_p(avi->val_, b), avi, b) {}
  void chain() {
    if (is_inf(avi_->val_)) {
      avi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }
    if (is_inf(bd_)) {
      avi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }

    // return zero derivative as gamma_p is flat
    // to machine precision for b / a > 10
    if (std::fabs(bd_ / avi_->val_) > 10)
      return;

    avi_->adj_ += adj_ * grad_reg_lower_inc_gamma(avi_->val_, bd_, 1.0e-10);
  }
};

class gamma_p_dv_vari : public op_dv_vari {
 public:
  gamma_p_dv_vari(double a, vari* bvi)
      : op_dv_vari(gamma_p(a, bvi->val_), a, bvi) {}
  void chain() {
    if (is_inf(ad_)) {
      bvi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }
    if (is_inf(bvi_->val_)) {
      bvi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }

    // return zero derivative as gamma_p is flat to
    // machine precision for b / a > 10
    if (std::fabs(bvi_->val_ / ad_) > 10)
      return;

    bvi_->adj_ += std::exp(std::log(adj_) - bvi_->val_
                           + (ad_ - 1.0) * std::log(bvi_->val_) - lgamma(ad_));
  }
};
}  // namespace

inline var gamma_p(const var& a, const var& b) {
  return var(new gamma_p_vv_vari(a.vi_, b.vi_));
}

inline var gamma_p(const var& a, double b) {
  return var(new gamma_p_vd_vari(a.vi_, b));
}

inline var gamma_p(double a, const var& b) {
  return var(new gamma_p_dv_vari(a, b.vi_));
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>Don't log gradients, they can be negative.<commit_after>#ifndef STAN_MATH_REV_SCAL_FUN_GAMMA_P_HPP
#define STAN_MATH_REV_SCAL_FUN_GAMMA_P_HPP

#include <stan/math/rev/core.hpp>
#include <stan/math/prim/scal/fun/is_inf.hpp>
#include <stan/math/prim/scal/err/domain_error.hpp>
#include <stan/math/prim/scal/fun/digamma.hpp>
#include <stan/math/prim/scal/fun/gamma_p.hpp>
#include <stan/math/prim/scal/fun/lgamma.hpp>
#include <stan/math/prim/scal/fun/grad_reg_lower_inc_gamma.hpp>
#include <valarray>
#include <limits>

namespace stan {
namespace math {

namespace {
class gamma_p_vv_vari : public op_vv_vari {
 public:
  gamma_p_vv_vari(vari* avi, vari* bvi)
      : op_vv_vari(gamma_p(avi->val_, bvi->val_), avi, bvi) {}
  void chain() {
    using boost::math::lgamma;
    using std::exp;
    using std::fabs;
    using std::log;

    if (is_inf(avi_->val_)) {
      avi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      bvi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }
    if (is_inf(bvi_->val_)) {
      avi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      bvi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }

    // return zero derivative as gamma_p is flat
    // to machine precision for b / a > 10
    if (std::fabs(bvi_->val_ / avi_->val_) > 10)
      return;

    avi_->adj_
        += adj_ * grad_reg_lower_inc_gamma(avi_->val_, bvi_->val_, 1.0e-10);
    bvi_->adj_ += adj_
                  * exp(-bvi_->val_ + (avi_->val_ - 1.0) * log(bvi_->val_)
                        - lgamma(avi_->val_));
  }
};

class gamma_p_vd_vari : public op_vd_vari {
 public:
  gamma_p_vd_vari(vari* avi, double b)
      : op_vd_vari(gamma_p(avi->val_, b), avi, b) {}
  void chain() {
    if (is_inf(avi_->val_)) {
      avi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }
    if (is_inf(bd_)) {
      avi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }

    // return zero derivative as gamma_p is flat
    // to machine precision for b / a > 10
    if (std::fabs(bd_ / avi_->val_) > 10)
      return;

    avi_->adj_ += adj_ * grad_reg_lower_inc_gamma(avi_->val_, bd_, 1.0e-10);
  }
};

class gamma_p_dv_vari : public op_dv_vari {
 public:
  gamma_p_dv_vari(double a, vari* bvi)
      : op_dv_vari(gamma_p(a, bvi->val_), a, bvi) {}
  void chain() {
    if (is_inf(ad_)) {
      bvi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }
    if (is_inf(bvi_->val_)) {
      bvi_->adj_ += std::numeric_limits<double>::quiet_NaN();
      return;
    }

    // return zero derivative as gamma_p is flat to
    // machine precision for b / a > 10
    if (std::fabs(bvi_->val_ / ad_) > 10)
      return;

    bvi_->adj_ += adj_ * exp(- bvi_->val_ + (ad_ - 1.0) * std::log(bvi_->val_) - lgamma(ad_));

  }
};
}  // namespace

inline var gamma_p(const var& a, const var& b) {
  return var(new gamma_p_vv_vari(a.vi_, b.vi_));
}

inline var gamma_p(const var& a, double b) {
  return var(new gamma_p_vd_vari(a.vi_, b));
}

inline var gamma_p(double a, const var& b) {
  return var(new gamma_p_dv_vari(a, b.vi_));
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/
/*=========================================================================
 *
 *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
 *
 *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 *
 *  For complete copyright, license and disclaimer of warranty information
 *  please refer to the NOTICE file at the top of the ITK source tree.
 *
 *=========================================================================*/
#ifndef itkImage_hxx
#define itkImage_hxx

#include "itkImage.h"
#include "itkProcessObject.h"
#include <algorithm>

namespace itk
{

template <typename TPixel, unsigned int VImageDimension>
Image<TPixel, VImageDimension>::Image()
{
  m_Buffer = PixelContainer::New();
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::Allocate(bool initializePixels)
{
  SizeValueType num;

  this->ComputeOffsetTable();
  num = static_cast<SizeValueType>(this->GetOffsetTable()[VImageDimension]);

  m_Buffer->Reserve(num, initializePixels);
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::Initialize()
{
  //
  // We don't modify ourselves because the "ReleaseData" methods depend upon
  // no modification when initialized.
  //

  // Call the superclass which should initialize the BufferedRegion ivar.
  Superclass::Initialize();

  // Replace the handle to the buffer. This is the safest thing to do,
  // since the same container can be shared by multiple images (e.g.
  // Grafted outputs and in place filters).
  m_Buffer = PixelContainer::New();
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::FillBuffer(const TPixel & value)
{
  const SizeValueType numberOfPixels = this->GetBufferedRegion().GetNumberOfPixels();

  std::fill_n(&(*m_Buffer)[0], numberOfPixels, value);
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::SetPixelContainer(PixelContainer * container)
{
  if (m_Buffer != container)
  {
    m_Buffer = container;
    this->Modified();
  }
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::Graft(const Self * image)
{
  // call the superclass' implementation
  Superclass::Graft(image);

  if (image)
  {
    // Now copy anything remaining that is needed
    this->SetPixelContainer(const_cast<PixelContainer *>(image->GetPixelContainer()));
  }
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::Graft(const DataObject * data)
{
  if (data)
  {
    // Attempt to cast data to an Image
    const auto * const imgData = dynamic_cast<const Self *>(data);

    if (imgData != nullptr)
    {
      this->Graft(imgData);
    }
    else
    {
      // pointer could not be cast back down
      itkExceptionMacro(<< "itk::Image::Graft() cannot cast " << typeid(data).name() << " to "
                        << typeid(const Self *).name());
    }
  }
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::ComputeIndexToPhysicalPointMatrices()
{
  this->Superclass::ComputeIndexToPhysicalPointMatrices();
}

template <typename TPixel, unsigned int VImageDimension>
unsigned int
Image<TPixel, VImageDimension>::GetNumberOfComponentsPerPixel() const
{
  // use the GetLength() method which works with variable length arrays,
  // to make it work with as much pixel types as possible
  const PixelType p{};
  return NumericTraits<PixelType>::GetLength(p);
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  os << indent << "PixelContainer: " << std::endl;
  m_Buffer->Print(os, indent.GetNextIndent());

  // m_Origin and m_Spacing are printed in the Superclass
}

} // end namespace itk

#endif
<commit_msg>COMP: Fix missing initializer warning<commit_after>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/
/*=========================================================================
 *
 *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
 *
 *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 *
 *  For complete copyright, license and disclaimer of warranty information
 *  please refer to the NOTICE file at the top of the ITK source tree.
 *
 *=========================================================================*/
#ifndef itkImage_hxx
#define itkImage_hxx

#include "itkImage.h"
#include "itkProcessObject.h"
#include <algorithm>

namespace itk
{

template <typename TPixel, unsigned int VImageDimension>
Image<TPixel, VImageDimension>::Image()
{
  m_Buffer = PixelContainer::New();
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::Allocate(bool initializePixels)
{
  SizeValueType num;

  this->ComputeOffsetTable();
  num = static_cast<SizeValueType>(this->GetOffsetTable()[VImageDimension]);

  m_Buffer->Reserve(num, initializePixels);
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::Initialize()
{
  //
  // We don't modify ourselves because the "ReleaseData" methods depend upon
  // no modification when initialized.
  //

  // Call the superclass which should initialize the BufferedRegion ivar.
  Superclass::Initialize();

  // Replace the handle to the buffer. This is the safest thing to do,
  // since the same container can be shared by multiple images (e.g.
  // Grafted outputs and in place filters).
  m_Buffer = PixelContainer::New();
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::FillBuffer(const TPixel & value)
{
  const SizeValueType numberOfPixels = this->GetBufferedRegion().GetNumberOfPixels();

  std::fill_n(&(*m_Buffer)[0], numberOfPixels, value);
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::SetPixelContainer(PixelContainer * container)
{
  if (m_Buffer != container)
  {
    m_Buffer = container;
    this->Modified();
  }
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::Graft(const Self * image)
{
  // call the superclass' implementation
  Superclass::Graft(image);

  if (image)
  {
    // Now copy anything remaining that is needed
    this->SetPixelContainer(const_cast<PixelContainer *>(image->GetPixelContainer()));
  }
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::Graft(const DataObject * data)
{
  if (data)
  {
    // Attempt to cast data to an Image
    const auto * const imgData = dynamic_cast<const Self *>(data);

    if (imgData != nullptr)
    {
      this->Graft(imgData);
    }
    else
    {
      // pointer could not be cast back down
      itkExceptionMacro(<< "itk::Image::Graft() cannot cast " << typeid(data).name() << " to "
                        << typeid(const Self *).name());
    }
  }
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::ComputeIndexToPhysicalPointMatrices()
{
  this->Superclass::ComputeIndexToPhysicalPointMatrices();
}

template <typename TPixel, unsigned int VImageDimension>
unsigned int
Image<TPixel, VImageDimension>::GetNumberOfComponentsPerPixel() const
{
  // use the GetLength() method which works with variable length arrays,
  // to make it work with as much pixel types as possible
  const auto p = PixelType();
  return NumericTraits<PixelType>::GetLength(p);
}

template <typename TPixel, unsigned int VImageDimension>
void
Image<TPixel, VImageDimension>::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  os << indent << "PixelContainer: " << std::endl;
  m_Buffer->Print(os, indent.GetNextIndent());

  // m_Origin and m_Spacing are printed in the Superclass
}

} // end namespace itk

#endif
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkImageToImageAffinePatternIntensityRegularStepGradientDescentRegistrationTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include "itkPhysicalImage.h"
#include "itkSimpleImageRegionIterator.h"
#include "itkImageToImageAffinePatternIntensityRegularStepGradientDescentRegistration.h"

/**
 *  This test uses two 2D-Gaussians (standard deviation RegionSize/2)
 *  One is shifted by 7,3 pixels from the other.
 *  therefore the solution of the registration is |-7 -3|
 *  This test uses LevenbergMarquart Optimizer but
 *  conjugate gradient optimizer tolerances are also defined
 *  in the itkImageToImageAffinePatternIntensityRegularStepGradientDescentRegistration.txx file
 *  (you need to change the type of the optimizer in the header file
 *  ie itkImageToImageAffinePatternIntensityRegularStepGradientDescentRegistration.h)
 */

int main()
{

  /*Allocate Images*/
  typedef itk::PhysicalImage<unsigned char,2>           ReferenceType;
  typedef itk::PhysicalImage<unsigned char,2>           TargetType;

  typedef itk::ImageToImageAffinePatternIntensityRegularStepGradientDescentRegistration<ReferenceType,TargetType> RegistrationType;

  ReferenceType::SizeType size = {{100,100}};
  ReferenceType::IndexType index = {{0,0}};
  ReferenceType::RegionType region;
  region.SetSize( size );
  region.SetIndex( index );

  ReferenceType::Pointer imgReference = ReferenceType::New();
  imgReference->SetLargestPossibleRegion( region );
  imgReference->SetBufferedRegion( region );
  imgReference->SetRequestedRegion( region );
  imgReference->Allocate();

  TargetType::Pointer imgTarget = TargetType::New();
  imgTarget->SetLargestPossibleRegion( region );
  imgTarget->SetBufferedRegion( region );
  imgTarget->SetRequestedRegion( region );
  imgTarget->Allocate();

  /* Fill images with a 2D gaussian*/
  typedef  itk::SimpleImageRegionIterator<ReferenceType> ReferenceIteratorType;

  typedef  itk::SimpleImageRegionIterator<TargetType> TargetIteratorType;

  itk::Point<double,2> center;
  center[0] = (double)region.GetSize()[0]/2.0;
  center[1] = (double)region.GetSize()[1]/2.0;

  const double s = (double)region.GetSize()[0]/2.0;

  itk::Point<double,2>  p;
  itk::Vector<double,2> d;

  /* Set the displacement */
  itk::Vector<double,2> displacement;
  displacement[0] = 7;
  displacement[1] = 3;

  ReferenceIteratorType ri(imgReference,region);
  TargetIteratorType ti(imgTarget,region);
  ri.Begin();
  while(!ri.IsAtEnd())
  {
    p[0] = ri.GetIndex()[0];
    p[1] = ri.GetIndex()[1];
    d = p-center;
    d += displacement;
    const double x = d[0];
    const double y = d[1];
    ri.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ri;
  }

  ti.Begin();
  while(!ti.IsAtEnd())
  {
    p[0] = ti.GetIndex()[0];
    p[1] = ti.GetIndex()[1];
    d = p-center;
    const double x = d[0];
    const double y = d[1];
    ti.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ti;
  }

  RegistrationType::Pointer registrationMethod = RegistrationType::New();

  registrationMethod->SetReference(imgReference);
  registrationMethod->SetTarget(imgTarget);
  registrationMethod->SetTranslationScale( 1e4 );

  registrationMethod->StartRegistration();

  std::cout << "The correct answer should be : " << std::endl;
  std::cout << " 1.0    0.0    0.0    1.0  ";
  std::cout << -displacement << std::endl;

  return EXIT_SUCCESS;

}
<commit_msg>ENH: Quantitative test added<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkImageToImageAffinePatternIntensityRegularStepGradientDescentRegistrationTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include "itkPhysicalImage.h"
#include "itkSimpleImageRegionIterator.h"
#include "itkImageToImageAffinePatternIntensityRegularStepGradientDescentRegistration.h"

/**
 *  This test uses two 2D-Gaussians (standard deviation RegionSize/2)
 *  One is shifted by 7,3 pixels from the other.
 *  therefore the solution of the registration is |-7 -3|
 *  This test uses LevenbergMarquart Optimizer but
 *  conjugate gradient optimizer tolerances are also defined
 *  in the itkImageToImageAffinePatternIntensityRegularStepGradientDescentRegistration.txx file
 *  (you need to change the type of the optimizer in the header file
 *  ie itkImageToImageAffinePatternIntensityRegularStepGradientDescentRegistration.h)
 */

int main()
{

  /*Allocate Images*/
  typedef itk::PhysicalImage<unsigned char,2>           ReferenceType;
  typedef itk::PhysicalImage<unsigned char,2>           TargetType;

  typedef itk::ImageToImageAffinePatternIntensityRegularStepGradientDescentRegistration<ReferenceType,TargetType> RegistrationType;

  ReferenceType::SizeType size = {{100,100}};
  ReferenceType::IndexType index = {{0,0}};
  ReferenceType::RegionType region;
  region.SetSize( size );
  region.SetIndex( index );

  ReferenceType::Pointer imgReference = ReferenceType::New();
  imgReference->SetLargestPossibleRegion( region );
  imgReference->SetBufferedRegion( region );
  imgReference->SetRequestedRegion( region );
  imgReference->Allocate();

  TargetType::Pointer imgTarget = TargetType::New();
  imgTarget->SetLargestPossibleRegion( region );
  imgTarget->SetBufferedRegion( region );
  imgTarget->SetRequestedRegion( region );
  imgTarget->Allocate();

  /* Fill images with a 2D gaussian*/
  typedef  itk::SimpleImageRegionIterator<ReferenceType> ReferenceIteratorType;

  typedef  itk::SimpleImageRegionIterator<TargetType> TargetIteratorType;

  itk::Point<double,2> center;
  center[0] = (double)region.GetSize()[0]/2.0;
  center[1] = (double)region.GetSize()[1]/2.0;

  const double s = (double)region.GetSize()[0]/2.0;

  itk::Point<double,2>  p;
  itk::Vector<double,2> d;

  /* Set the displacement */
  itk::Vector<double,2> displacement;
  displacement[0] = 7;
  displacement[1] = 3;

  ReferenceIteratorType ri(imgReference,region);
  TargetIteratorType ti(imgTarget,region);
  ri.Begin();
  while(!ri.IsAtEnd())
  {
    p[0] = ri.GetIndex()[0];
    p[1] = ri.GetIndex()[1];
    d = p-center;
    d += displacement;
    const double x = d[0];
    const double y = d[1];
    ri.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ri;
  }

  ti.Begin();
  while(!ti.IsAtEnd())
  {
    p[0] = ti.GetIndex()[0];
    p[1] = ti.GetIndex()[1];
    d = p-center;
    const double x = d[0];
    const double y = d[1];
    ti.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ti;
  }

  RegistrationType::Pointer registrationMethod = RegistrationType::New();

  const double translationScale = 1e4;

  registrationMethod->SetReference(imgReference);
  registrationMethod->SetTarget(imgTarget);
  registrationMethod->SetTranslationScale( translationScale );

  registrationMethod->StartRegistration();

  // get the results
  RegistrationType::ParametersType solution =
    registrationMethod->GetOptimizer()->GetCurrentPosition();

  std::cout << "Solution is: " << solution << std::endl;

  //
  // check results to see if it is within range
  //
  bool pass = true;
  double trueParameters[6] = { 1, 0, 0, 1, -7, -3 };
  for( unsigned int j = 0; j < 4; j++ )
    {
    if( vnl_math_abs( solution[j] - trueParameters[j] ) > 0.02 )
      {
      std::cout << j << " ";
      std::cout << solution[j] << " ";
      std::cout << trueParameters[j] << " ";
      std::cout << vnl_math_abs( solution[j] - trueParameters[j] ) << " ";
      std::cout << std::endl;
      pass = false;
      }
    }
  for( unsigned int j = 4; j < 6; j++ )
    {
    if( vnl_math_abs( solution[j] * translationScale
                      - trueParameters[j] ) > 1.0 )
      {
      std::cout << j << " ";
      std::cout << solution[j] << " ";
      std::cout << trueParameters[j] << " ";
      std::cout << vnl_math_abs( solution[j] - trueParameters[j] ) << " ";
      std::cout << std::endl;
      pass = false;
      }
    }

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>#include <chi/Context.hpp>
#include <chi/LLVMVersion.hpp>
#include <chi/Result.hpp>

#include <llvm/IR/Module.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Linker/Linker.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_os_ostream.h>

#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/Interpreter.h>
#include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/ObjectCache.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>

#include <string>
#include <vector>

#include <boost/program_options.hpp>

namespace po = boost::program_options;

int interpret(const std::vector<std::string>& opts, const char* argv0) {
	po::options_description interpret_ops("interpret options");
	interpret_ops.add_options()(
	    "input-file,i",
	    po::value<std::vector<std::string>>()->default_value(std::vector<std::string>({"-"}), "-"),
	    "Input file, - for stdin")("optimization,O", po::value<int>()->default_value(2),
	                               "Optimization value, either 0, 1, 2, or 3")(
	    "function,f", po::value<std::string>()->default_value("main"), "The function to run")(
	    "subargs", po::value<std::vector<std::string>>(), "arguments for command");

	po::positional_options_description pos;
	pos.add("subargs", -1);

	po::variables_map vm;

	auto parsed_options = po::command_line_parser(opts)
	                          .options(interpret_ops)
	                          .positional(pos)
	                          .allow_unregistered()
	                          .run();
	po::store(parsed_options, vm);
	po::notify(vm);

	std::vector<std::string> command_opts =
	    po::collect_unrecognized(parsed_options.options, po::include_positional);
	// add the name into it
	command_opts.insert(command_opts.begin(), argv0);

	auto infiles = vm["input-file"].as<std::vector<std::string>>();

	// get opt value
	llvm::CodeGenOpt::Level optLevel;
	switch (vm["optimization"].as<int>()) {
	case 0: optLevel = llvm::CodeGenOpt::None; break;
	case 1: optLevel = llvm::CodeGenOpt::Less; break;
	case 2: optLevel = llvm::CodeGenOpt::Default; break;
	case 3: optLevel = llvm::CodeGenOpt::Aggressive; break;
	default:
		std::cerr << "Unrecognized optimization level: " << vm["optimization"].as<int>()
		          << std::endl;
		return 1;
	}

	chi::Context ctx;

	// load the modules
	std::deque<std::unique_ptr<llvm::Module>> mods;
	for (const auto& file : infiles) {
		llvm::SMDiagnostic err;

		// this recognizes stdin correctly
		auto mod = llvm::parseIRFile(file, err, ctx.llvmContext());

		if (mod == nullptr) {
			llvm::raw_os_ostream errstream(std::cerr);
			std::cerr << "Failed to read IR: " << std::endl;
			err.print("chig", errstream);
			std::cerr << std::endl;

			return 1;
		}
		mods.push_back(std::move(mod));
	}

	// link them all together
	std::unique_ptr<llvm::Module> realMod = std::move(mods[0]);
	mods.pop_front();

	while (!mods.empty()) {
#if LLVM_VERSION_LESS_EQUAL(3, 7)
		llvm::Linker::LinkModules(realMod.get(), mods[0].get());
#else
		llvm::Linker::linkModules(*realMod, std::move(mods[0]));
#endif
		mods.pop_front();
	}

	// run it
	llvm::Function* func = realMod->getFunction(vm["function"].as<std::string>());

	if (func == nullptr) {
		std::cerr << "Failed to find function in module: " << vm["function"].as<std::string>()
		          << std::endl;

		return 1;
	}

	int ret;

	auto res = chi::interpretLLVMIRAsMain(std::move(realMod), optLevel, command_opts, func, &ret);
	if (!res) {
		std::cerr << "Faied to run module: " << std::endl << res << std::endl;
		return 1;
	}

	return ret;
}
<commit_msg>Fix linker command<commit_after>#include <chi/Context.hpp>
#include <chi/LLVMVersion.hpp>
#include <chi/Result.hpp>

#include <llvm/IR/Module.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Linker/Linker.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_os_ostream.h>

#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/Interpreter.h>
#include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/ObjectCache.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>

#include <string>
#include <vector>

#include <boost/program_options.hpp>

namespace po = boost::program_options;

int interpret(const std::vector<std::string>& opts, const char* argv0) {
	po::options_description interpret_ops("interpret options");
	interpret_ops.add_options()(
	    "input-file,i",
	    po::value<std::vector<std::string>>()->default_value(std::vector<std::string>({"-"}), "-"),
	    "Input file, - for stdin")("optimization,O", po::value<int>()->default_value(2),
	                               "Optimization value, either 0, 1, 2, or 3")(
	    "function,f", po::value<std::string>()->default_value("main"), "The function to run")(
	    "subargs", po::value<std::vector<std::string>>(), "arguments for command");

	po::positional_options_description pos;
	pos.add("subargs", -1);

	po::variables_map vm;

	auto parsed_options = po::command_line_parser(opts)
	                          .options(interpret_ops)
	                          .positional(pos)
	                          .allow_unregistered()
	                          .run();
	po::store(parsed_options, vm);
	po::notify(vm);

	std::vector<std::string> command_opts =
	    po::collect_unrecognized(parsed_options.options, po::include_positional);
	// add the name into it
	command_opts.insert(command_opts.begin(), argv0);

	auto infiles = vm["input-file"].as<std::vector<std::string>>();

	// get opt value
	llvm::CodeGenOpt::Level optLevel;
	switch (vm["optimization"].as<int>()) {
	case 0: optLevel = llvm::CodeGenOpt::None; break;
	case 1: optLevel = llvm::CodeGenOpt::Less; break;
	case 2: optLevel = llvm::CodeGenOpt::Default; break;
	case 3: optLevel = llvm::CodeGenOpt::Aggressive; break;
	default:
		std::cerr << "Unrecognized optimization level: " << vm["optimization"].as<int>()
		          << std::endl;
		return 1;
	}

	chi::Context ctx;

	// load the modules
	std::deque<std::unique_ptr<llvm::Module>> mods;
	for (const auto& file : infiles) {
		llvm::SMDiagnostic err;

		// this recognizes stdin correctly
		auto mod = llvm::
#if LLVM_VERSION_LESS_EQUAL(3, 5)
			ParseIRFile
#else
			parseIRFile
#endif
				(file, err, ctx.llvmContext());

		if (mod == nullptr) {
			llvm::raw_os_ostream errstream(std::cerr);
			std::cerr << "Failed to read IR: " << std::endl;
			err.print("chig", errstream);
			std::cerr << std::endl;

			return 1;
		}
		mods.push_back(std::move(mod));
	}

	// link them all together
	std::unique_ptr<llvm::Module> realMod = std::move(mods[0]);
	mods.pop_front();

	while (!mods.empty()) {
#if LLVM_VERSION_LESS_EQUAL(3, 7)
		llvm::Linker::LinkModules(realMod.get(), mods[0].get()
#if LLVM_VERSION_LESS_EQUAL(3, 5)
		, llvm::Linker::DestroySource, nullptr
#endif
		);
#else
		llvm::Linker::linkModules(*realMod, std::move(mods[0]));
#endif
		mods.pop_front();
	}

	// run it
	llvm::Function* func = realMod->getFunction(vm["function"].as<std::string>());

	if (func == nullptr) {
		std::cerr << "Failed to find function in module: " << vm["function"].as<std::string>()
		          << std::endl;

		return 1;
	}

	int ret;

	auto res = chi::interpretLLVMIRAsMain(std::move(realMod), optLevel, command_opts, func, &ret);
	if (!res) {
		std::cerr << "Faied to run module: " << std::endl << res << std::endl;
		return 1;
	}

	return ret;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
// #include <stdlib>
#include <string>
#include <vector>

#include <TFile.h>
#include <TTreeReader.h>
#include <TTreeReaderValue.h>
#include <TTreeReaderArray.h>

#include <avro.h>

#define NA ((uint64_t)(-1))

using namespace ROOT::Internal;   // for TTreeReaderValueBase

// global variables for this tiny, single-threaded program (parallelism comes from multiple processes)
std::vector<std::string> fileLocations;
std::string              treeLocation;
uint64_t                 start = NA;
uint64_t                 end = NA;
std::vector<std::string> exclude;
std::vector<std::string> only;

std::string              codec("null");
avro_schema_t            schema;
avro_schema_error_t      schemaError;
bool                     schemaDefined = false;
avro_file_writer_t       avroWriter;
avro_value_iface_t       *avroInterface;
avro_value_t             avroValue;

void help() {
  std::cerr << "Usage: root2avro fileLocation1, [fileLocation2, [...]], treeLocation" << std::endl << std::endl
            << "Where fileLocationN are either file paths or URLs TFile::Open can handle and treeLocation is the path of the" << std::endl
            << "TTree in all the files." << std::endl << std::endl
            << "Avro is streamed to standard output and can be redirected to a file." << std::endl << std::endl
            << "Options:" << std::endl
            << "  --start=NUMBER         First entry number to convert." << std::endl
            << "  --end=NUMBER           Entry number after the last to convert." << std::endl
            << "  --exclude=FIELDS       Comma-delimited field (leaf) names to exclude, if any." << std::endl
            << "  --only=FIELDS          Comma-delimited field (leaf) names to restrict to, if provided." << std::endl
            << "  --codec=CODEC          Codec for compressing the Avro output; may be \"null\" (uncompressed, default)," << std::endl
            << "                         \"deflate\", \"snappy\", \"lzma\", depending on libraries installed on your system." << std::endl
            << "  -h, -help, --help      Print this message and exit." << std::endl;
}

std::vector<std::string> splitByComma(std::string in) {
  std::vector<std::string> out;
  std::stringstream ss(in);
  std::string item;
  while (std::getline(ss, item, ','))
    out.push_back(item);
  return out;
}

int main(int argc, char **argv) {
  // no, I don't care about the inefficiency of creating and recreating strings; this is not an important loop
  for (int i = 0;  i < argc;  i++) {
    if (std::string(argv[i]) == std::string("-h")  ||
        std::string(argv[i]) == std::string("-help")  ||
        std::string(argv[i]) == std::string("--help")) {
      help();
      return 0;
    }
  }

  std::string startPrefix("--start=");
  std::string endPrefix("--end=");
  std::string excludePrefix("--exclude=");
  std::string onlyPrefix("--only=");
  std::string codecPrefix("--codec=");
  std::string badPrefix("-");

  // nor is this an important loop
  for (int i = 0;  i < argc;  i++) {
    std::string arg(argv[i]);

    if (arg.substr(0, startPrefix.size()) == startPrefix) {
      std::string value = arg.substr(startPrefix.size(), arg.size());
      start = strtoul(value.c_str(), nullptr, 10);
    }

    else if (arg.substr(0, endPrefix.size()) == endPrefix) {
      std::string value = arg.substr(endPrefix.size(), arg.size());
      end = strtoul(value.c_str(), nullptr, 10);
    }

    else if (arg.substr(0, excludePrefix.size()) == excludePrefix)
      exclude = splitByComma(arg.substr(excludePrefix.size(), arg.size()));

    else if (arg.substr(0, onlyPrefix.size()) == onlyPrefix)
      only = splitByComma(arg.substr(onlyPrefix.size(), arg.size()));

    else if (arg.substr(0, codecPrefix.size()) == codecPrefix)
      codec = arg.substr(codecPrefix.size(), arg.size());

    else if (arg.substr(0, badPrefix.size()) == badPrefix) {
      std::cerr << "Recognized switches are: --start, --end, --exclude, --only, --codec." << std::endl;
      return -1;
    }

    else
      fileLocations.push_back(arg);
  }

  if (fileLocations.size() < 2) {
    std::cerr << "At least two (non-switch) arguments are required." << std::endl;
    return -1;
  }
  treeLocation = fileLocations.back();
  fileLocations.pop_back();

  if (start != NA  &&  end != NA  &&  start >= end) {
    std::cerr << "Start must be less than end (if provided)." << std::endl;
    return -1;
  }

  std::string schemastr("{\"type\": \"record\", \"name\": \"Stuff\", \"fields\": [{\"name\": \"one\", \"type\": \"int\"}, {\"name\": \"two\", \"type\": \"double\"}, {\"name\": \"three\", \"type\": \"string\"}]}");

  if (avro_schema_from_json(schemastr.c_str(), schemastr.size(), &schema, &schemaError) != 0) {
    std::cerr << avro_strerror() << std::endl;
    return -1;
  }
  schemaDefined = true;

  avroInterface = avro_generic_class_from_schema(schema);
  if (avroInterface == nullptr) {
    std::cerr << avro_strerror() << std::endl;
    return -1;
  }

  if (avro_generic_value_new(avroInterface, &avroValue) != 0) {
    std::cerr << avro_strerror() << std::endl;
    return -1;
  }

  avro_value_t one;
  avro_value_t two;
  avro_value_t three;

  if (avro_value_get_by_name(&avroValue, "one", &one, nullptr) != 0) {
    std::cerr << avro_strerror() << std::endl;
    return -1;
  }

  if (avro_value_get_by_name(&avroValue, "two", &two, nullptr) != 0) {
    std::cerr << avro_strerror() << std::endl;
    return -1;
  }

  if (avro_value_get_by_name(&avroValue, "three", &three, nullptr) != 0) {
    std::cerr << avro_strerror() << std::endl;
    return -1;
  }

  std::string path;
  if (avro_file_writer_create_with_codec_fp(stdout, path.c_str(), true, schema, &avroWriter, codec.c_str(), 0) != 0) {
    std::cerr << avro_strerror() << std::endl;
    return -1;
  }

  for (int i = 0;  i < 10;  i++) {
    avro_value_set_int(&one, i);
    avro_value_set_double(&two, i + i/10.0);
    avro_value_set_string(&three, std::to_string(i).c_str());
    avro_file_writer_append_value(avroWriter, &avroValue);
  }

  avro_file_writer_close(avroWriter);

  // uint64_t entry = 0;
  // for (int i = 0;  i < fileLocations.size();  i++) {
  //   std::string message = convertFile(fileLocations[i], entry);
  //   if (message != std::string("")) {
  //     std::cerr << message << std::endl;
  //     return -1;
  //   }
  // }

  return 0;
}

// int64_t newFile(const char *fileLocation) {
//   return (int64_t)TFile::Open(fileLocation);
// }

// int64_t newReader(int64_t file, const char *treeLocation) {
//   TFile *p_file = (TFile*)file;
//   return (int64_t)(new TTreeReader(treeLocation, p_file));
// }

// bool readerNext(int64_t reader) {
//   TTreeReader *p_reader = (TTreeReader*)reader;
//   return p_reader->Next();
// }

// int64_t newValue_float(int64_t reader, const char *name) {
//   TTreeReader *p_reader = (TTreeReader*)reader;
//   return (int64_t)(new TTreeReaderValue<float>(*p_reader, name));
// }

// float getValue_float(int64_t value) {
//   TTreeReaderValueBase *p_value = (TTreeReaderValueBase*)value;
//   return *((float*)p_value->GetAddress());
// }
<commit_msg>getting good information from ROOT<commit_after>#include <iostream>
#include <sstream>
#include <string>
#include <vector>

// #include <TROOT.h>
// #include <TInterpreter.h>
#include <TFile.h>
#include <TTree.h>
// #include <TTreeReader.h>
// #include <TTreeReaderValue.h>
// #include <TTreeReaderArray.h>
#include <TTreeProxyGenerator.h>
#include <TBranchProxyDescriptor.h>
#include <TBranchProxyClassDescriptor.h>

#include <avro.h>

#define NA ((uint64_t)(-1))

using namespace ROOT::Internal;

// global variables for this tiny, single-threaded program (parallelism comes from multiple processes)
std::vector<std::string> fileLocations;
std::string              treeLocation;
uint64_t                 start = NA;
uint64_t                 end = NA;
// std::vector<std::string> exclude;     // replace these with some ROOT selector string, if possible
// std::vector<std::string> only;
bool                     schemaOnly = false;
std::string              codec("null");

avro_schema_t            schema;
avro_schema_error_t      schemaError;
bool                     schemaDefined = false;
avro_file_writer_t       avroWriter;
avro_value_iface_t       *avroInterface;
avro_value_t             avroValue;

void help() {
  std::cerr << "Usage: root2avro fileLocation1, [fileLocation2, [...]], treeLocation" << std::endl << std::endl
            << "Where fileLocationN are either file paths or URLs TFile::Open can handle and treeLocation is the path of the" << std::endl
            << "TTree in all the files." << std::endl << std::endl
            << "Avro is streamed to standard output and can be redirected to a file." << std::endl << std::endl
            << "Options:" << std::endl
            << "  --start=NUMBER         First entry number to convert." << std::endl
            << "  --end=NUMBER           Entry number after the last to convert." << std::endl
            // << "  --exclude=FIELDS       Comma-delimited field (leaf) names to exclude, if any." << std::endl
            // << "  --only=FIELDS          Comma-delimited field (leaf) names to restrict to, if provided." << std::endl
            << "  --schema               Output the schema only (JSON), rather than data (Avro)." << std::endl
            << "  --codec=CODEC          Codec for compressing the Avro output; may be \"null\" (uncompressed, default)," << std::endl
            << "                         \"deflate\", \"snappy\", \"lzma\", depending on libraries installed on your system." << std::endl
            << "  -h, -help, --help      Print this message and exit." << std::endl;
}

// std::vector<std::string> splitByComma(std::string in) {
//   std::vector<std::string> out;
//   std::stringstream ss(in);
//   std::string item;
//   while (std::getline(ss, item, ','))
//     out.push_back(item);
//   return out;
// }

int main(int argc, char **argv) {
  // no, I don't care about the inefficiency of creating and recreating strings; this is not an important loop
  for (int i = 1;  i < argc;  i++) {
    if (std::string(argv[i]) == std::string("-h")  ||
        std::string(argv[i]) == std::string("-help")  ||
        std::string(argv[i]) == std::string("--help")) {
      help();
      return 0;
    }
  }

  std::string startPrefix("--start=");
  std::string endPrefix("--end=");
  // std::string excludePrefix("--exclude=");
  // std::string onlyPrefix("--only=");
  std::string codecPrefix("--codec=");
  std::string badPrefix("-");

  // nor is this an important loop
  for (int i = 1;  i < argc;  i++) {
    std::string arg(argv[i]);

    if (arg.substr(0, startPrefix.size()) == startPrefix) {
      std::string value = arg.substr(startPrefix.size(), arg.size());
      start = strtoul(value.c_str(), nullptr, 10);
    }

    else if (arg.substr(0, endPrefix.size()) == endPrefix) {
      std::string value = arg.substr(endPrefix.size(), arg.size());
      end = strtoul(value.c_str(), nullptr, 10);
    }

    // else if (arg.substr(0, excludePrefix.size()) == excludePrefix)
    //   exclude = splitByComma(arg.substr(excludePrefix.size(), arg.size()));

    // else if (arg.substr(0, onlyPrefix.size()) == onlyPrefix)
    //   only = splitByComma(arg.substr(onlyPrefix.size(), arg.size()));

    else if (arg == std::string("--schema"))
      schemaOnly = true;

    else if (arg.substr(0, codecPrefix.size()) == codecPrefix)
      codec = arg.substr(codecPrefix.size(), arg.size());

    else if (arg.substr(0, badPrefix.size()) == badPrefix) {
      std::cerr << "Recognized switches are: --start, --end, --schema, --codec." << std::endl;
      return -1;
    }

    else
      fileLocations.push_back(arg);
  }

  if (fileLocations.size() < 2) {
    std::cerr << "At least two (non-switch) arguments are required." << std::endl;
    return -1;
  }
  treeLocation = fileLocations.back();
  fileLocations.pop_back();

  if (start != NA  &&  end != NA  &&  start >= end) {
    std::cerr << "Start must be less than end (if provided)." << std::endl;
    return -1;
  }

  TFile *file = TFile::Open(fileLocations[0].c_str());
  TTree *tree;
  file->GetObject(treeLocation.c_str(), tree);

  std::string empty;
  TTreeProxyGenerator *generator = new TTreeProxyGenerator(tree, empty.c_str(), empty.c_str(), empty.c_str(), (uint32_t)(-1));

  if (true) {
    std::cout << "Forwards:" << std::endl;
    TIter next(&generator->fListOfForwards);
    for (TObject *current = next();  current != nullptr;  current = next()) {
      std::cout << "    " << current->GetTitle();
    }
    std::cout << std::endl;
  }

  if (true) {
    std::cout << "Headers:" << std::endl;
    TIter next(&generator->fListOfHeaders);
    for (TObject *header = next();  header != nullptr;  header = next()) {
      std::cout << "    " << header->GetTitle();
    }
    std::cout << std::endl;
  }

  if (true) {
    std::cout << "Top proxies:" << std::endl;
    TIter next(&generator->fListOfTopProxies);
    for (TBranchProxyDescriptor *data = (TBranchProxyDescriptor*)next();  data != nullptr;  data = (TBranchProxyDescriptor*)next()) {
      std::cout << "    " << data->GetDataName() << "\t\t" << data->GetTypeName() << "\t\t" << data->GetBranchName() << std::endl;
    }
    std::cout << std::endl;
  }

  if (true) {
    std::cout << "Wrappers for classes:" << std::endl;
    TIter next(&generator->fListOfClasses);
    for (TBranchProxyClassDescriptor *clp = (TBranchProxyClassDescriptor*)next();  clp != nullptr;  clp = (TBranchProxyClassDescriptor*)next()) {
      std::cout << "    " << clp->GetBranchName() << "\t\t" << clp->GetSubBranchPrefix() << "\t\t" << clp->GetRawSymbol() << "\t\t" << clp->IsClones() << " " << clp->IsSTL() << " " << clp->GetContainerName() << std::endl;
    }
  }

  // std::string schemastr("{\"type\": \"record\", \"name\": \"Stuff\", \"fields\": [{\"name\": \"one\", \"type\": \"int\"}, {\"name\": \"two\", \"type\": \"double\"}, {\"name\": \"three\", \"type\": \"string\"}]}");

  // if (avro_schema_from_json(schemastr.c_str(), schemastr.size(), &schema, &schemaError) != 0) {
  //   std::cerr << avro_strerror() << std::endl;
  //   return -1;
  // }
  // schemaDefined = true;

  // avroInterface = avro_generic_class_from_schema(schema);
  // if (avroInterface == nullptr) {
  //   std::cerr << avro_strerror() << std::endl;
  //   return -1;
  // }

  // if (avro_generic_value_new(avroInterface, &avroValue) != 0) {
  //   std::cerr << avro_strerror() << std::endl;
  //   return -1;
  // }

  // avro_value_t one;
  // avro_value_t two;
  // avro_value_t three;

  // if (avro_value_get_by_name(&avroValue, "one", &one, nullptr) != 0) {
  //   std::cerr << avro_strerror() << std::endl;
  //   return -1;
  // }

  // if (avro_value_get_by_name(&avroValue, "two", &two, nullptr) != 0) {
  //   std::cerr << avro_strerror() << std::endl;
  //   return -1;
  // }

  // if (avro_value_get_by_name(&avroValue, "three", &three, nullptr) != 0) {
  //   std::cerr << avro_strerror() << std::endl;
  //   return -1;
  // }

  // std::string path;
  // if (avro_file_writer_create_with_codec_fp(stdout, path.c_str(), true, schema, &avroWriter, codec.c_str(), 0) != 0) {
  //   std::cerr << avro_strerror() << std::endl;
  //   return -1;
  // }

  // for (int i = 0;  i < 10;  i++) {
  //   avro_value_set_int(&one, i);
  //   avro_value_set_double(&two, i + i/10.0);
  //   avro_value_set_string(&three, std::to_string(i).c_str());
  //   avro_file_writer_append_value(avroWriter, &avroValue);
  // }

  // avro_file_writer_close(avroWriter);

  // uint64_t entry = 0;
  // for (int i = 0;  i < fileLocations.size();  i++) {
  //   std::string message = convertFile(fileLocations[i], entry);
  //   if (message != std::string("")) {
  //     std::cerr << message << std::endl;
  //     return -1;
  //   }
  // }

  return 0;
}
<|endoftext|>


<commit_before>// $B%X%C%@%U%!%$%k$N%$%s%/%k!<%I(B
// $B4{Dj$N%X%C%@(B
#include <iostream> // C++$BI8=`F~=PNO(B
// $BFH<+$N%X%C%@(B
#include "public.h" // $B%/%i%9(Bclass_public

// class_public$B$N%a%s%P$NDj5A(B.
// $B%a%s%P4X?t(Bprint_base()
void class_public::print_base(){ // class_base$B$N%a%s%P$r=PNO(B.

  // class_base$B$N%a%s%P$r=PNO(B.
  //private_variable_ = 1; // private$B$J$N$G%"%/%;%9IT2D(B.
  //private_function(); // private$B$J$N$G%"%/%;%9IT2D(B.
  protected_variable_ = 1; // protected$B$J$N$G%"%/%;%92D(B.
  std::cout << "protected_variable_ = " << protected_variable_ << std::endl; // protected$B$J$N$G%"%/%;%92D(B.
  protected_function(); // protected$B$J$N$G%"%/%;%92D(B.
  public_variable_ = 1; // public$B$J$N$G%"%/%;%92D(B.
  std::cout << "public_variable_ = " << public_variable_ << std::endl; // public$B$J$N$G%"%/%;%92D(B.
  public_function(); // public$B$J$N$G%"%/%;%92D(B.

}

<commit_msg>fixed public.cpp<commit_after>// 独自のヘッダ
#include "public.h" // クラスclass_public

// class_publicのメンバの定義.
// メンバ関数print_base()
void class_public::print_base(){ // class_baseのメンバを出力.

  // class_baseのメンバを出力.
  //private_variable_ = 1; // privateなのでアクセス不可.
  //private_function(); // privateなのでアクセス不可.
  protected_variable_ = 1; // protectedなのでアクセス可.
  std::cout << "protected_variable_ = " << protected_variable_ << std::endl; // protectedなのでアクセス可.
  protected_function(); // protectedなのでアクセス可.
  public_variable_ = 1; // publicなのでアクセス可.
  std::cout << "public_variable_ = " << public_variable_ << std::endl; // publicなのでアクセス可.
  public_function(); // publicなのでアクセス可.

}
<|endoftext|>


<commit_before>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <math.h>

#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include "Draw2D.h"
#include "AppSDL2OGL.h"

#include "fastmath.h"
#include "Vec2.h"
#include "geom2D.h"

#include "TerrainHydraulics.h"
#include "testUtils.h"

// ======================  TestApp

class TestAppTerrainHydraulics : public AppSDL2OGL{
	public:
    int perframe = 3;
    TerrainHydraulics terrain;
    int shape;
    bool running = true;

	// ---- function declarations

	virtual void draw   ();
	virtual void drawHUD();
    virtual void eventHandling( const SDL_Event& event );
	//virtual int tileToList( float x0, float y0, float x1, float y1 );

    void renderMapContent ( float x0, float y0, float scale, float csc, float hsc );
    double terrain_color( int i );
	//void drawSimplexGrid( int n, float step );

	TestAppTerrainHydraulics( int& id, int WIDTH_, int HEIGHT_ );

};

double TestAppTerrainHydraulics::terrain_color( int i ){
    float g   = terrain.ground[i];
    float w   = terrain.water [i];
    if( w > g ){
        float c = (1-20*(w-g)); if(c<0) c=0;
        glColor3f(g*g*c,0.2+0.8*g*(1-g)*c,1.0);
    }else{
        glColor3f(g*g,0.2+0.8*(1-g)*g,0);
    }
    return g;
}

void TestAppTerrainHydraulics::renderMapContent( float x0, float y0, float scale, float csc, float hsc ){
    //glColor3f( 0.1f,0.1f,0.1f );
    Vec2f a,b,p;
    a.set( 1.0d, 0.0d           ); a.mul(scale);
    b.set( 0.5d, 0.86602540378d ); b.mul(scale);
    //glDisable(GL_SMOOTH);
    int ii = 0;
    for (int iy=0; iy<terrain.ny-1; iy+=1){
        glBegin( GL_TRIANGLE_STRIP );
        for (int ix=0; ix<terrain.nx; ix+=1){
            p.set( ix*a.x+iy*b.x + x0, ix*a.y+iy*b.y + y0 );
            //val = terrain.ground[ii              ]; w = terrain.water[ii              ];    c = csc * val;  glColor3f(c,c,w);  glVertex3f( p.x    , p.y    , val*hsc );
            //val = terrain.ground[ii + terrain.nx ]; w = terrain.water[ii + terrain.nx ];    c = csc * val;  glColor3f(c,c,w);  glVertex3f( p.x+b.x, p.y+b.y, val*hsc );

            terrain_color( ii               ); glVertex3f( p.x    , p.y    , 0 );
            terrain_color( ii + terrain.nx  ); glVertex3f( p.x+b.x, p.y+b.y, 0 );

            //val = sin(p.x    )*sin(p.y    ); c = cscale * val;  glColor3f(c,c,c);  glVertex3f( p.x    , p.y    , val*hscale );
            //val = sin(p.x+b.x)*sin(p.y+b.y); c = cscale * val;  glColor3f(c,c,c);  glVertex3f( p.x+b.x, p.y+b.y, val*hscale );

            //glColor3f(randf(),randf(),randf()); glVertex3f( p.x    , p.y    , 0 );
            //glColor3f(randf(),randf(),randf()); glVertex3f( p.x+b.x, p.y+b.y, 0 );
            //printf( "%i, %i %f \n", iy, ix, val );
            ii++;
        }
        glEnd();
    }
}

TestAppTerrainHydraulics::TestAppTerrainHydraulics( int& id, int WIDTH_, int HEIGHT_ ) : AppSDL2OGL( id, WIDTH_, HEIGHT_ ) {

    terrain.allocate( 512, 512 );
    //terrain.genTerrainNoise( 14, 0.3, 0.7, 0.6, 45454, {1000.0,1000.0} );
    //terrain.genTerrainNoise( 14, 0.5, 1.0,  0.7, 1.2, 45454, {100.0,100.0} );
    terrain.genTerrainNoise( 8, 2.0, 1.0,  0.5, 0.8, 45454, {100.0,100.0} );

/*
    shape=glGenLists(1);
	glNewList( shape, GL_COMPILE );
        renderMapContent( -0.1*terrain.nx, -0.1*terrain.ny,  0.2, 1.0, 1.0 );
	glEndList();
*/

/*
    terrain.init_outflow();
    for ( int ii=0; ii<50; ii++){
        int i = rand()%terrain.ntot;
        terrain.contour2[ii] = i;
        terrain.nContour++;
        terrain.water[i] = terrain.ground[i];

    }
    //for (int i=0; i<terrain.ntot; i++){  terrain.water[i] = terrain.ground[i]; }
*/

    //for (int i=0; i<terrain.ntot; i++){  terrain.water[i] = 1.0; terrain.water_[i] = 1.0; }
    terrain.initErrosion( 1.0 );

    shape=glGenLists(1);
}

void TestAppTerrainHydraulics::draw(){
    glClearColor( 0.5f, 0.5f, 0.5f, 0.0f );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glDisable( GL_DEPTH_TEST );
    long t0;
    if( running ){
        t0 = getCPUticks();
        //perframe = 1;
        for( int i=0; i<perframe; i++ ){
            //terrain.outflow_step();
            //if( terrain.nContour == 0 ){  running=false; break; }
            //terrain.rain_and_evaporation(); terrain.flow_errosion_step();

            int npix = terrain.flow_errosion_step_noRain( );  if( npix < terrain.nx ){ running = false;}
            //terrain.errodeDroples( 1000, 100, 0.01 );
        }
        long tcomp = getCPUticks() - t0;
        t0    = getCPUticks();
        if( running ){
            renderMapContent( -0.1*terrain.nx, -0.1*terrain.ny,  0.2, 1.0, 1.0 );
        }else{
            glNewList( shape, GL_COMPILE );
            renderMapContent( -0.1*terrain.nx, -0.1*terrain.ny,  0.2, 1.0, 1.0 );
            glEndList();
        }
        long tplot = getCPUticks() - t0;
        printf( " tplot %3.3f Mtick tcomp %3.3f Mtick ( %3.3f ticks/pix ) \n", tplot*1e-6, tcomp*1e-6, ((double)tcomp)/(terrain.ntot*perframe) );
    }else{
        glCallList( shape );
    }

    //renderMapContent( );

};

void TestAppTerrainHydraulics::drawHUD(){}

void TestAppTerrainHydraulics::eventHandling( const SDL_Event& event ){
    switch( event.type ){
        case SDL_KEYDOWN :
            switch( event.key.keysym.sym ){
                case SDLK_r:  terrain.initErrosion( 0.8 ); running=true;  break;
            }
            break;
         /*
        case SDL_MOUSEBUTTONDOWN:
            switch( event.button.button ){
                case SDL_BUTTON_LEFT:
                    //paintSimplex( mouse_begin_x, mouse_begin_y );
                    mouse_left  = true;
                    break;
                case SDL_BUTTON_RIGHT:
                    mouse_right = true;
                    //eraseSimplex( mouse_begin_x, mouse_begin_y );
                    break;
            }
            break;
        case SDL_MOUSEBUTTONUP:
            switch( event.button.button ){
                case SDL_BUTTON_LEFT:
                    mouse_left = false;
                    break;
                case SDL_BUTTON_RIGHT:
                    mouse_right = false;
                    break;
            }
            break;
        */
    };
    AppSDL2OGL::eventHandling( event );
};

// ===================== MAIN

TestAppTerrainHydraulics * testApp;

int main(int argc, char *argv[]){

	SDL_Init(SDL_INIT_VIDEO);
	SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
	int junk;
	testApp = new TestAppTerrainHydraulics( junk , 800, 600 );
	testApp->loop( 1000000 );
	return 0;
}

<commit_msg>TerrainHydraulics sequential Erode and flood<commit_after>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <math.h>

#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include "Draw2D.h"
#include "AppSDL2OGL.h"

#include "fastmath.h"
#include "Vec2.h"
#include "geom2D.h"

#include "TerrainHydraulics.h"
#include "testUtils.h"

// ======================  TestApp

class TestAppTerrainHydraulics : public AppSDL2OGL{
	public:
    int job_type = 1;
    int perframe = 3;
    TerrainHydraulics terrain;
    int shape;
    bool running = true;

	// ---- function declarations

	virtual void draw   ();
	virtual void drawHUD();
    virtual void eventHandling( const SDL_Event& event );
	//virtual int tileToList( float x0, float y0, float x1, float y1 );

    void renderMapContent ( float x0, float y0, float scale, float csc, float hsc );
    double terrain_color( int i );
	//void drawSimplexGrid( int n, float step );

	TestAppTerrainHydraulics( int& id, int WIDTH_, int HEIGHT_ );

};

double TestAppTerrainHydraulics::terrain_color( int i ){
    float g   = terrain.ground[i];
    float w   = terrain.water [i];
    if( w > g ){
        float c = (1-20*(w-g)); if(c<0) c=0;
        glColor3f(g*g*c,0.2+0.8*g*(1-g)*c,0.5);
    }else{
        glColor3f(g*g,0.2+0.8*(1-g)*g,0);
    }
    return g;
}

void TestAppTerrainHydraulics::renderMapContent( float x0, float y0, float scale, float csc, float hsc ){
    //glColor3f( 0.1f,0.1f,0.1f );
    Vec2f a,b,p;
    a.set( 1.0d, 0.0d           ); a.mul(scale);
    b.set( 0.5d, 0.86602540378d ); b.mul(scale);
    //glDisable(GL_SMOOTH);
    int ii = 0;
    for (int iy=0; iy<terrain.ny-1; iy+=1){
        glBegin( GL_TRIANGLE_STRIP );
        for (int ix=0; ix<terrain.nx; ix+=1){
            p.set( ix*a.x+iy*b.x + x0, ix*a.y+iy*b.y + y0 );
            //val = terrain.ground[ii              ]; w = terrain.water[ii              ];    c = csc * val;  glColor3f(c,c,w);  glVertex3f( p.x    , p.y    , val*hsc );
            //val = terrain.ground[ii + terrain.nx ]; w = terrain.water[ii + terrain.nx ];    c = csc * val;  glColor3f(c,c,w);  glVertex3f( p.x+b.x, p.y+b.y, val*hsc );

            terrain_color( ii               ); glVertex3f( p.x    , p.y    , 0 );
            terrain_color( ii + terrain.nx  ); glVertex3f( p.x+b.x, p.y+b.y, 0 );

            //val = sin(p.x    )*sin(p.y    ); c = cscale * val;  glColor3f(c,c,c);  glVertex3f( p.x    , p.y    , val*hscale );
            //val = sin(p.x+b.x)*sin(p.y+b.y); c = cscale * val;  glColor3f(c,c,c);  glVertex3f( p.x+b.x, p.y+b.y, val*hscale );

            //glColor3f(randf(),randf(),randf()); glVertex3f( p.x    , p.y    , 0 );
            //glColor3f(randf(),randf(),randf()); glVertex3f( p.x+b.x, p.y+b.y, 0 );
            //printf( "%i, %i %f \n", iy, ix, val );
            ii++;
        }
        glEnd();
    }
}

TestAppTerrainHydraulics::TestAppTerrainHydraulics( int& id, int WIDTH_, int HEIGHT_ ) : AppSDL2OGL( id, WIDTH_, HEIGHT_ ) {

    terrain.allocate( 512, 512 );
    //terrain.genTerrainNoise( 14, 0.3, 0.7, 0.6, 45454, {1000.0,1000.0} );
    //terrain.genTerrainNoise( 14, 0.5, 1.0,  0.7, 1.2, 45454, {100.0,100.0} );
    terrain.genTerrainNoise( 8, 2.0, 1.0,  0.5, 0.8, 45454, {100.0,100.0} );

/*
    shape=glGenLists(1);
	glNewList( shape, GL_COMPILE );
        renderMapContent( -0.1*terrain.nx, -0.1*terrain.ny,  0.2, 1.0, 1.0 );
	glEndList();
*/

    //for (int i=0; i<terrain.ntot; i++){  terrain.water[i] = terrain.ground[i]; }

    //for (int i=0; i<terrain.ntot; i++){  terrain.water[i] = 1.0; terrain.water_[i] = 1.0; }
    terrain.initErrosion( 1.0 );

    shape=glGenLists(1);
}

void TestAppTerrainHydraulics::draw(){
    glClearColor( 0.5f, 0.5f, 0.5f, 0.0f );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glDisable( GL_DEPTH_TEST );
    long t0;
    if( running ){
        t0 = getCPUticks();
        //perframe = 1;
        for( int i=0; i<perframe; i++ ){
            switch(job_type){
                case 1: {
                    int npix = terrain.flow_errosion_step_noRain( );
                    if( npix < terrain.nx ){
                        job_type = 2;
                        terrain.init_outflow();
                        for ( int ii=0; ii<50; ii++){
                            int i = rand()%terrain.ntot;
                            terrain.contour2[ii] = i;
                            terrain.nContour++;
                            terrain.water[i] = terrain.ground[i];
                        }
                        //running = false;
                    }
                    //terrain.errodeDroples( 1000, 100, 0.01 );
                    break; }
                case 2:{
                    terrain.outflow_step();
                    if( terrain.nContour == 0 ){
                        //job_type = 2;
                        running=false; break;
                    }
                    break;}
            }
        }
        long tcomp = getCPUticks() - t0;
        t0    = getCPUticks();
        if( running ){
            renderMapContent( -0.1*terrain.nx, -0.1*terrain.ny,  0.2, 1.0, 1.0 );
        }else{
            glNewList( shape, GL_COMPILE );
            renderMapContent( -0.1*terrain.nx, -0.1*terrain.ny,  0.2, 1.0, 1.0 );
            glEndList();
        }
        long tplot = getCPUticks() - t0;
        printf( " tplot %3.3f Mtick tcomp %3.3f Mtick ( %3.3f ticks/pix ) \n", tplot*1e-6, tcomp*1e-6, ((double)tcomp)/(terrain.ntot*perframe) );
    }else{
        glCallList( shape );
    }

    //renderMapContent( );

};

void TestAppTerrainHydraulics::drawHUD(){}

void TestAppTerrainHydraulics::eventHandling( const SDL_Event& event ){
    switch( event.type ){
        case SDL_KEYDOWN :
            switch( event.key.keysym.sym ){
                case SDLK_r:  terrain.initErrosion( 0.8 ); running=true;  break;
            }
            break;
         /*
        case SDL_MOUSEBUTTONDOWN:
            switch( event.button.button ){
                case SDL_BUTTON_LEFT:
                    //paintSimplex( mouse_begin_x, mouse_begin_y );
                    mouse_left  = true;
                    break;
                case SDL_BUTTON_RIGHT:
                    mouse_right = true;
                    //eraseSimplex( mouse_begin_x, mouse_begin_y );
                    break;
            }
            break;
        case SDL_MOUSEBUTTONUP:
            switch( event.button.button ){
                case SDL_BUTTON_LEFT:
                    mouse_left = false;
                    break;
                case SDL_BUTTON_RIGHT:
                    mouse_right = false;
                    break;
            }
            break;
        */
    };
    AppSDL2OGL::eventHandling( event );
};

// ===================== MAIN

TestAppTerrainHydraulics * testApp;

int main(int argc, char *argv[]){

	SDL_Init(SDL_INIT_VIDEO);
	SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
	int junk;
	testApp = new TestAppTerrainHydraulics( junk , 800, 600 );
	testApp->loop( 1000000 );
	return 0;
}

<|endoftext|>