<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 "geocodingtab.h"
#include "placepresenter.h"

#include <QTreeWidget>
#include <QLineEdit>
#include <QString>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QMessageBox>
#include <QDialogButtonBox>

#include <qgeoaddress.h>

GeoCodingInputDialog::GeoCodingInputDialog(QString &obloc, QGeoAddress &address, QWidget *parent)
    : QDialog(parent), m_oblocStr(obloc), m_address(address)
{
    setWindowTitle(tr("Geocoding Parameters"));
    QLabel *obloclbl = new QLabel(tr("OneBox-Search:"));
    m_obloc = new QLineEdit(m_oblocStr);
    m_obloc->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);

    QLabel *addressSearchlbl = new QLabel(tr("Search by address (Leave OneBox empty):"));
    QLabel *countrylbl = new QLabel(tr("Country:"));
    m_country = new QLineEdit(address.country());
    m_country->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    QLabel *statelbl = new QLabel(tr("State:"));
    m_state = new QLineEdit(address.state());
    m_state->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    QLabel *citylbl = new QLabel(tr("City:"));
    m_city = new QLineEdit(address.city());
    m_city->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    QLabel *ziplbl = new QLabel(tr("Zip:"));
    m_zip = new QLineEdit(address.postCode());
    m_zip->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    QLabel *streetlbl = new QLabel(tr("Street:"));
    m_street = new QLineEdit(address.street());
    m_street->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    QHBoxLayout *firstrow = new QHBoxLayout;
    firstrow->setSpacing(2);
    firstrow->setContentsMargins(2, 1, 2, 1);
    firstrow->addWidget(m_obloc);

    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel,Qt::Horizontal);
    connect(buttonBox,SIGNAL(accepted()),this,SLOT(accept()));
    connect(buttonBox,SIGNAL(rejected()),this,SLOT(reject()));

    QGridLayout *gridLayout = new QGridLayout ;
    gridLayout->setSizeConstraint(QLayout::SetMinimumSize);
    gridLayout->setSpacing(2);
    gridLayout->setContentsMargins(2, 1, 2, 1);

    gridLayout->addWidget(streetlbl, 1, 0);
    gridLayout->addWidget(m_street, 2, 0,1,2);

    gridLayout->addWidget(ziplbl, 3, 0);
    gridLayout->addWidget(citylbl, 3, 1);
    gridLayout->addWidget(m_zip, 4, 0);
    gridLayout->addWidget(m_city, 4, 1);

    gridLayout->addWidget(statelbl, 5, 0);
    gridLayout->addWidget(countrylbl, 5, 1);
    gridLayout->addWidget(m_state, 6, 0);
    gridLayout->addWidget(m_country, 6, 1);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);
    mainLayout->setSpacing(2);
    mainLayout->setContentsMargins(2, 1, 2, 1);
    mainLayout->addWidget(obloclbl);
    mainLayout->addLayout(firstrow);
    mainLayout->addWidget(addressSearchlbl);
    mainLayout->addLayout(gridLayout);
    mainLayout->addWidget(buttonBox);
    setLayout(mainLayout);

}

void GeoCodingInputDialog::accept()
{
    m_oblocStr = m_obloc->text();

    m_address.setCountry(m_country->text());
    m_address.setState(m_state->text());
    m_address.setCity(m_city->text());
    m_address.setPostCode(m_zip->text());
    m_address.setStreet(m_street->text());

    QDialog::accept();
}

GeocodingTab::GeocodingTab(QWidget *parent) :
        QWidget(parent),
        m_searchManager(NULL)
{

    m_oblocStr="Deutschland, Mnchen";

    m_requestBtn = new QPushButton(tr("Search By Address"));
    m_requestBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    m_requestBtn->setDisabled(true);
    QObject::connect(m_requestBtn, SIGNAL(clicked(bool)), this, SLOT(on_btnRequest_clicked()));

    m_resultTree = new QTreeWidget();
    QStringList labels;
    labels << tr("Elements") << tr("Value");
    m_resultTree->setHeaderLabels(labels);
    m_resultTree->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_resultTree->setColumnWidth(0, 240);

    QHBoxLayout *firstrow = new QHBoxLayout;
    firstrow->setSpacing(2);
    firstrow->setContentsMargins(2, 1, 2, 1);
    firstrow->addWidget(m_requestBtn);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->setSpacing(2);
    mainLayout->setContentsMargins(2, 1, 2, 1);
    mainLayout->addLayout(firstrow);
    mainLayout->addWidget(m_resultTree);
    setLayout(mainLayout);
}

GeocodingTab::~GeocodingTab()
{
}

void GeocodingTab::initialize(QGeoSearchManager *searchManager)
{
    m_resultTree->clear();
    m_searchManager = searchManager;
    if (m_searchManager) {
        QObject::connect(m_searchManager, SIGNAL(finished(QGeoSearchReply*)), this,
                         SLOT(replyFinished(QGeoSearchReply*)));
        QObject::connect(m_searchManager,
                         SIGNAL(error(QGeoSearchReply*, QGeoSearchReply::Error, QString)), this,
                         SLOT(resultsError(QGeoSearchReply*, QGeoSearchReply::Error, QString)));
        if (m_searchManager->supportsGeocoding())
            m_requestBtn->setDisabled(false);
    } else
        m_requestBtn->setDisabled(true);

}

void GeocodingTab::on_btnRequest_clicked()
{
    if (m_searchManager) {
        GeoCodingInputDialog dlg(m_oblocStr,m_address,this);
        if(dlg.exec()==QDialog::Accepted) {
            m_resultTree->clear();
            QTreeWidgetItem* top = new QTreeWidgetItem(m_resultTree);
            top->setText(0, tr("Geocode"));
            top->setText(1, tr("Requesting data"));

            if (!m_oblocStr.isEmpty()) {
                m_searchManager->search(m_oblocStr, QGeoSearchManager::SearchGeocode);
            } else {
                m_searchManager->geocode(m_address);
            }
        }
    } else {
        QMessageBox::warning(this, tr("Geocoding"), tr("No search manager available."));
    }
}

void GeocodingTab::replyFinished(QGeoSearchReply* reply)
{
    if (!isHidden() && reply->error() == QGeoSearchReply::NoError) {
        PlacePresenter presenter(m_resultTree, reply);
        presenter.show();
        reply->deleteLater();
    }
}

void GeocodingTab::resultsError(QGeoSearchReply* reply, QGeoSearchReply::Error errorCode, QString errorString)
{
    Q_UNUSED(errorCode)

    if (!isHidden()) {
        QTreeWidgetItem* errorResultItem = new QTreeWidgetItem(m_resultTree);
        errorResultItem->setText(0, tr("Error"));
        errorResultItem->setText(1, errorString);
        reply->deleteLater();
    }
}
<commit_msg>Fixes: MOBILITY-1431 GeoServiceDemo UI issues on Maemo5<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 "geocodingtab.h"
#include "placepresenter.h"

#include <QTreeWidget>
#include <QLineEdit>
#include <QString>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QMessageBox>
#include <QDialogButtonBox>

#include <qgeoaddress.h>

GeoCodingInputDialog::GeoCodingInputDialog(QString &obloc, QGeoAddress &address, QWidget *parent)
    : QDialog(parent), m_oblocStr(obloc), m_address(address)
{
    setWindowTitle(tr("Geocoding Parameters"));
    QLabel *obloclbl = new QLabel(tr("OneBox-Search:"));
    m_obloc = new QLineEdit(m_oblocStr);
    m_obloc->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);

    QLabel *addressSearchlbl = new QLabel(tr("Search by address (Leave OneBox empty):"));
    QLabel *countrylbl = new QLabel(tr("Country:"));
    m_country = new QLineEdit(address.country());
    m_country->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    QLabel *statelbl = new QLabel(tr("State:"));
    m_state = new QLineEdit(address.state());
    m_state->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    QLabel *citylbl = new QLabel(tr("City:"));
    m_city = new QLineEdit(address.city());
    m_city->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    QLabel *ziplbl = new QLabel(tr("Zip:"));
    m_zip = new QLineEdit(address.postCode());
    m_zip->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    QLabel *streetlbl = new QLabel(tr("Street:"));
    m_street = new QLineEdit(address.street());
    m_street->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    QHBoxLayout *firstrow = new QHBoxLayout;
    firstrow->setSpacing(2);
    firstrow->setContentsMargins(2, 1, 2, 1);
    firstrow->addWidget(m_obloc);

    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel,Qt::Horizontal);
    connect(buttonBox,SIGNAL(accepted()),this,SLOT(accept()));
    connect(buttonBox,SIGNAL(rejected()),this,SLOT(reject()));

    QGridLayout *gridLayout = new QGridLayout ;
    gridLayout->setSizeConstraint(QLayout::SetMinimumSize);
    gridLayout->setSpacing(2);
    gridLayout->setContentsMargins(2, 1, 2, 1);
#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
    gridLayout->addWidget(streetlbl, 1, 0);
    gridLayout->addWidget(m_street, 1, 1,1,3);

    gridLayout->addWidget(ziplbl, 2, 0);
    gridLayout->addWidget(citylbl, 2, 2);
    gridLayout->addWidget(m_zip, 2, 1);
    gridLayout->addWidget(m_city, 2, 3);

    gridLayout->addWidget(statelbl, 3, 0);
    gridLayout->addWidget(countrylbl, 3, 2);
    gridLayout->addWidget(m_state, 3, 1);
    gridLayout->addWidget(m_country, 3, 3);
#else
    gridLayout->addWidget(streetlbl, 1, 0);
    gridLayout->addWidget(m_street, 2, 0,1,2);

    gridLayout->addWidget(ziplbl, 3, 0);
    gridLayout->addWidget(citylbl, 3, 1);
    gridLayout->addWidget(m_zip, 4, 0);
    gridLayout->addWidget(m_city, 4, 1);

    gridLayout->addWidget(statelbl, 5, 0);
    gridLayout->addWidget(countrylbl, 5, 1);
    gridLayout->addWidget(m_state, 6, 0);
    gridLayout->addWidget(m_country, 6, 1);
#endif
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);
    mainLayout->setSpacing(2);
    mainLayout->setContentsMargins(2, 1, 2, 1);
    mainLayout->addWidget(obloclbl);
    mainLayout->addLayout(firstrow);
    mainLayout->addWidget(addressSearchlbl);
    mainLayout->addLayout(gridLayout);
    mainLayout->addWidget(buttonBox);
    setLayout(mainLayout);

}

void GeoCodingInputDialog::accept()
{
    m_oblocStr = m_obloc->text();

    m_address.setCountry(m_country->text());
    m_address.setState(m_state->text());
    m_address.setCity(m_city->text());
    m_address.setPostCode(m_zip->text());
    m_address.setStreet(m_street->text());

    QDialog::accept();
}

GeocodingTab::GeocodingTab(QWidget *parent) :
        QWidget(parent),
        m_searchManager(NULL)
{

    m_oblocStr="Deutschland, Mnchen";

    m_requestBtn = new QPushButton(tr("Search By Address"));
    m_requestBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    m_requestBtn->setDisabled(true);
    QObject::connect(m_requestBtn, SIGNAL(clicked(bool)), this, SLOT(on_btnRequest_clicked()));

    m_resultTree = new QTreeWidget();
    QStringList labels;
    labels << tr("Elements") << tr("Value");
    m_resultTree->setHeaderLabels(labels);
    m_resultTree->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_resultTree->setColumnWidth(0, 240);

    QHBoxLayout *firstrow = new QHBoxLayout;
    firstrow->setSpacing(2);
    firstrow->setContentsMargins(2, 1, 2, 1);
    firstrow->addWidget(m_requestBtn);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->setSpacing(2);
    mainLayout->setContentsMargins(2, 1, 2, 1);
    mainLayout->addLayout(firstrow);
    mainLayout->addWidget(m_resultTree);
    setLayout(mainLayout);
}

GeocodingTab::~GeocodingTab()
{
}

void GeocodingTab::initialize(QGeoSearchManager *searchManager)
{
    m_resultTree->clear();
    m_searchManager = searchManager;
    if (m_searchManager) {
        QObject::connect(m_searchManager, SIGNAL(finished(QGeoSearchReply*)), this,
                         SLOT(replyFinished(QGeoSearchReply*)));
        QObject::connect(m_searchManager,
                         SIGNAL(error(QGeoSearchReply*, QGeoSearchReply::Error, QString)), this,
                         SLOT(resultsError(QGeoSearchReply*, QGeoSearchReply::Error, QString)));
        if (m_searchManager->supportsGeocoding())
            m_requestBtn->setDisabled(false);
    } else
        m_requestBtn->setDisabled(true);

}

void GeocodingTab::on_btnRequest_clicked()
{
    if (m_searchManager) {
        GeoCodingInputDialog dlg(m_oblocStr,m_address,this);
        if(dlg.exec()==QDialog::Accepted) {
            m_resultTree->clear();
            QTreeWidgetItem* top = new QTreeWidgetItem(m_resultTree);
            top->setText(0, tr("Geocode"));
            top->setText(1, tr("Requesting data"));

            if (!m_oblocStr.isEmpty()) {
                m_searchManager->search(m_oblocStr, QGeoSearchManager::SearchGeocode);
            } else {
                m_searchManager->geocode(m_address);
            }
        }
    } else {
        QMessageBox::warning(this, tr("Geocoding"), tr("No search manager available."));
    }
}

void GeocodingTab::replyFinished(QGeoSearchReply* reply)
{
    if (!isHidden() && reply->error() == QGeoSearchReply::NoError) {
        PlacePresenter presenter(m_resultTree, reply);
        presenter.show();
        reply->deleteLater();
    }
}

void GeocodingTab::resultsError(QGeoSearchReply* reply, QGeoSearchReply::Error errorCode, QString errorString)
{
    Q_UNUSED(errorCode)

    if (!isHidden()) {
        QTreeWidgetItem* errorResultItem = new QTreeWidgetItem(m_resultTree);
        errorResultItem->setText(0, tr("Error"));
        errorResultItem->setText(1, errorString);
        reply->deleteLater();
    }
}
<|endoftext|>


<commit_before>/*
 * people_det.cpp
 *
 *  Created on: Oct 20, 2015
 *      Author: Tzutalin
 */

#include <string.h>
#include <jni.h>
#include <android/log.h>
#include <string>
#include <stdio.h>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/opencv/cv_image.h>
#include <dlib/image_loader/load_image.h>

#define  LOG_TAG    "People_Det-JNI"
#define  LOGV(...)  __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG, __VA_ARGS__)
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__)
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG, __VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, __VA_ARGS__)

class OpencvHOGDetctor {
public:
    OpencvHOGDetctor() {
    }

    inline int det(std::string path) {
        LOGD("det path %s", path.c_str());
        cv::Mat src_img = cv::imread(path, 1);
        if (src_img.empty())
            return 0;

        cv::HOGDescriptor hog;
        hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
        std::vector<cv::Rect> found, found_filtered;
        hog.detectMultiScale(src_img, found, 0, cv::Size(8, 8),
                cv::Size(32, 32), 1.05, 2);
        size_t i, j;
        for (i = 0; i < found.size(); i++) {
            cv::Rect r = found[i];
            for (j = 0; j < found.size(); j++)
                if (j != i && (r & found[j]) == r)
                    break;
            if (j == found.size())
                found_filtered.push_back(r);
        }

        for (i = 0; i < found_filtered.size(); i++) {
            cv::Rect r = found_filtered[i];
            r.x += cvRound(r.width * 0.1);
            r.width = cvRound(r.width * 0.8);
            r.y += cvRound(r.height * 0.06);
            r.height = cvRound(r.height * 0.9);
            cv::rectangle(src_img, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2);
        }
        mResultMat = src_img;
        //cv::imwrite(path, mResultMat);
        LOGD("det ends");
        mRets = found_filtered;
        return found_filtered.size();
    }

    inline cv::Mat& getResultMat() {
        return mResultMat;
    }

    inline std::vector<cv::Rect> getResult() {
        return mRets;
    }

private:
    cv::Mat mResultMat;
    std::vector<cv::Rect> mRets;
};

class DLibHOGFaceDetector {
public:
    DLibHOGFaceDetector() {

    }

    inline int det(std::string path) {
        dlib::frontal_face_detector detector =
                dlib::get_frontal_face_detector();
        dlib::array2d<dlib::rgb_pixel> img;
        load_image(img, path);
        //dlib::pyramid_up(img);
        mRets = detector(img);
        LOGD("Dlib HOG face det size : %d", mRets.size());

        // Draw on the input for test
        int i = 0;
        cv::Mat src_img = cv::imread(path, 1);
        for (i = 0; i < mRets.size(); i++) {
            dlib::rectangle dlibrect = mRets[i];
            cv::Rect r(dlibrect.left(), dlibrect.top(), dlibrect.width(),
                    dlibrect.height());
            r.x += cvRound(r.width * 0.1);
            r.width = cvRound(r.width * 0.8);
            r.y += cvRound(r.height * 0.06);
            r.height = cvRound(r.height * 0.9);
            cv::rectangle(src_img, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2);
        }
        //cv::imwrite(path, src_img);
        return mRets.size();
    }

    inline std::vector<dlib::rectangle> getResult() {
        return mRets;
    }

private:
    std::string mModel;
    std::vector<dlib::rectangle> mRets;
};

OpencvHOGDetctor* mOpencvHOGDetctor = NULL;
DLibHOGFaceDetector* mDlibFaceDetector = NULL;

#ifdef __cplusplus
extern "C" {
#endif

struct VisionDetRetOffsets {
    jfieldID label;
    jfieldID confidence;
    jfieldID left;
    jfieldID top;
    jfieldID right;
    jfieldID bottom;
} gVisionDetRetOffsets;

// ========================================================
// JNI Mapping Methods
// ========================================================
jint JNIEXPORT JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    LOGE("JNI On Load");
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
        LOGE("GetEnv failed!");
        return result;
    }

    return JNI_VERSION_1_6;
}

void JNIEXPORT
JNICALL Java_com_tzutalin_dlib_PeopleDet_jniNativeClassInit(JNIEnv *_env,
        jclass _this) {
    jclass detRetClass = _env->FindClass("com/tzutalin/dlib/VisionDetRet");
    gVisionDetRetOffsets.label = _env->GetFieldID(detRetClass, "mLabel",
            "java/lang/String");
    gVisionDetRetOffsets.confidence = _env->GetFieldID(detRetClass,
            "mConfidence", "F");
    gVisionDetRetOffsets.left = _env->GetFieldID(detRetClass, "mLeft", "I");
    gVisionDetRetOffsets.top = _env->GetFieldID(detRetClass, "mTop", "I");
    gVisionDetRetOffsets.right = _env->GetFieldID(detRetClass, "mRight", "I");
    gVisionDetRetOffsets.bottom = _env->GetFieldID(detRetClass, "mBottom", "I");
    LOGD("JniNativeClassIni Success");
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniOpencvHOGDetect(
        JNIEnv* env, jobject thiz, jstring imgPath)
{
    LOGD("com_tzutalin_dlib_PeopleDet jniOpencvHOGDetect");
    const char *img_path = env->GetStringUTFChars(imgPath, 0);
    if(mOpencvHOGDetctor == NULL)
        mOpencvHOGDetctor = new OpencvHOGDetctor();

    int nums = mOpencvHOGDetctor->det(std::string(img_path));
    env->ReleaseStringUTFChars(imgPath, img_path);
    return nums;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniGetOpecvHOGRet(JNIEnv* env,
        jobject thiz, jobject detRet, jint index)
{
    if (mOpencvHOGDetctor) {
        cv::Rect rect = mOpencvHOGDetctor->getResult()[index];
        env->SetIntField(detRet, gVisionDetRetOffsets.left, rect.x);
        env->SetIntField(detRet, gVisionDetRetOffsets.top, rect.y);
        env->SetIntField(detRet, gVisionDetRetOffsets.right, rect.x + rect.width);
        env->SetIntField(detRet, gVisionDetRetOffsets.bottom, rect.y + rect.height);
        env->SetFloatField(detRet, gVisionDetRetOffsets.confidence, 0);
        jstring jstr=(jstring)(env->NewStringUTF("person"));
        env->SetObjectField(detRet, gVisionDetRetOffsets.label, (jobject)jstr);
        return 0;
    }
    return -1;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniDLibHOGDetect(
        JNIEnv* env, jobject thiz, jstring imgPath, jobject detRet)
{
    LOGD("com_tzutalin_dlib_PeopleDet jniDLibHOGDetect");
    const char *img_path = env->GetStringUTFChars(imgPath, 0);
    if(mDlibFaceDetector == NULL)
        mDlibFaceDetector = new DLibHOGFaceDetector();

    int size = mDlibFaceDetector->det(std::string(img_path));
    env->ReleaseStringUTFChars(imgPath, img_path);
    return size;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniGetDLibRet(JNIEnv* env,
        jobject thiz, jobject detRet, jint index)
{
    if (mDlibFaceDetector) {
        dlib::rectangle rect = mDlibFaceDetector->getResult()[index];
        env->SetIntField(detRet, gVisionDetRetOffsets.left, rect.left());
        env->SetIntField(detRet, gVisionDetRetOffsets.top, rect.top());
        env->SetIntField(detRet, gVisionDetRetOffsets.right, rect.right());
        env->SetIntField(detRet, gVisionDetRetOffsets.bottom, rect.bottom());
        env->SetFloatField(detRet, gVisionDetRetOffsets.confidence, 0);
        jstring jstr=(jstring)(env->NewStringUTF("face"));
        env->SetObjectField(detRet, gVisionDetRetOffsets.label, (jobject)jstr);
        return 0;
    }
    return -1;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniInit(JNIEnv* env, jobject thiz)
{

    if(mDlibFaceDetector == NULL)
        mDlibFaceDetector = new DLibHOGFaceDetector();

    if (mOpencvHOGDetctor == NULL)
        mOpencvHOGDetctor = new OpencvHOGDetctor();

    return 0;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniDeInit(JNIEnv* env, jobject thiz)
{
    if(mDlibFaceDetector)
        delete mDlibFaceDetector;

    if (mOpencvHOGDetctor)
        delete mOpencvHOGDetctor;

    return 0;
}

#ifdef __cplusplus
}
#endif
<commit_msg>DLib Facedetection will read image from openCV<commit_after>/*
 * people_det.cpp
 *
 *  Created on: Oct 20, 2015
 *      Author: Tzutalin
 */

#include <string.h>
#include <jni.h>
#include <android/log.h>
#include <string>
#include <stdio.h>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/opencv/cv_image.h>
#include <dlib/image_loader/load_image.h>

#define  LOG_TAG    "People_Det-JNI"
#define  LOGV(...)  __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG, __VA_ARGS__)
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__)
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG, __VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, __VA_ARGS__)

class OpencvHOGDetctor {
public:
    OpencvHOGDetctor() {
    }

    inline int det(std::string path) {
        LOGD("det path %s", path.c_str());
        cv::Mat src_img = cv::imread(path, 1);
        if (src_img.empty())
            return 0;

        cv::HOGDescriptor hog;
        hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
        std::vector<cv::Rect> found, found_filtered;
        hog.detectMultiScale(src_img, found, 0, cv::Size(8, 8),
                cv::Size(32, 32), 1.05, 2);
        size_t i, j;
        for (i = 0; i < found.size(); i++) {
            cv::Rect r = found[i];
            for (j = 0; j < found.size(); j++)
                if (j != i && (r & found[j]) == r)
                    break;
            if (j == found.size())
                found_filtered.push_back(r);
        }

        for (i = 0; i < found_filtered.size(); i++) {
            cv::Rect r = found_filtered[i];
            r.x += cvRound(r.width * 0.1);
            r.width = cvRound(r.width * 0.8);
            r.y += cvRound(r.height * 0.06);
            r.height = cvRound(r.height * 0.9);
            cv::rectangle(src_img, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2);
        }
        mResultMat = src_img;
        //cv::imwrite(path, mResultMat);
        LOGD("det ends");
        mRets = found_filtered;
        return found_filtered.size();
    }

    inline cv::Mat& getResultMat() {
        return mResultMat;
    }

    inline std::vector<cv::Rect> getResult() {
        return mRets;
    }

private:
    cv::Mat mResultMat;
    std::vector<cv::Rect> mRets;
};

class DLibHOGFaceDetector {
public:
    DLibHOGFaceDetector() {

    }

    inline int det(std::string path) {
        dlib::frontal_face_detector detector =
                dlib::get_frontal_face_detector();

        cv::Mat src_img = cv::imread(path, 1);
        dlib::cv_image<dlib::bgr_pixel> img(src_img);

        mRets = detector(img);
        LOGD("Dlib HOG face det size : %d", mRets.size());

        /*
        // Draw on the input for test
        int i = 0;
        for (i = 0; i < mRets.size(); i++) {
            dlib::rectangle dlibrect = mRets[i];
            cv::Rect r(dlibrect.left(), dlibrect.top(), dlibrect.width(),
                    dlibrect.height());
            r.x += cvRound(r.width * 0.1);
            r.width = cvRound(r.width * 0.8);
            r.y += cvRound(r.height * 0.06);
            r.height = cvRound(r.height * 0.9);
            cv::rectangle(src_img, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2);
        }
        cv::imwrite(path, src_img);
        */
        return mRets.size();
    }

    inline std::vector<dlib::rectangle> getResult() {
        return mRets;
    }

private:
    std::string mModel;
    std::vector<dlib::rectangle> mRets;
};

OpencvHOGDetctor* mOpencvHOGDetctor = NULL;
DLibHOGFaceDetector* mDlibFaceDetector = NULL;

#ifdef __cplusplus
extern "C" {
#endif

struct VisionDetRetOffsets {
    jfieldID label;
    jfieldID confidence;
    jfieldID left;
    jfieldID top;
    jfieldID right;
    jfieldID bottom;
} gVisionDetRetOffsets;

// ========================================================
// JNI Mapping Methods
// ========================================================
jint JNIEXPORT JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    LOGE("JNI On Load");
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
        LOGE("GetEnv failed!");
        return result;
    }

    return JNI_VERSION_1_6;
}

void JNIEXPORT
JNICALL Java_com_tzutalin_dlib_PeopleDet_jniNativeClassInit(JNIEnv *_env,
        jclass _this) {
    jclass detRetClass = _env->FindClass("com/tzutalin/dlib/VisionDetRet");
    gVisionDetRetOffsets.label = _env->GetFieldID(detRetClass, "mLabel",
            "java/lang/String");
    gVisionDetRetOffsets.confidence = _env->GetFieldID(detRetClass,
            "mConfidence", "F");
    gVisionDetRetOffsets.left = _env->GetFieldID(detRetClass, "mLeft", "I");
    gVisionDetRetOffsets.top = _env->GetFieldID(detRetClass, "mTop", "I");
    gVisionDetRetOffsets.right = _env->GetFieldID(detRetClass, "mRight", "I");
    gVisionDetRetOffsets.bottom = _env->GetFieldID(detRetClass, "mBottom", "I");
    LOGD("JniNativeClassIni Success");
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniOpencvHOGDetect(
        JNIEnv* env, jobject thiz, jstring imgPath)
{
    LOGD("com_tzutalin_dlib_PeopleDet jniOpencvHOGDetect");
    const char *img_path = env->GetStringUTFChars(imgPath, 0);
    if(mOpencvHOGDetctor == NULL)
        mOpencvHOGDetctor = new OpencvHOGDetctor();

    int nums = mOpencvHOGDetctor->det(std::string(img_path));
    env->ReleaseStringUTFChars(imgPath, img_path);
    return nums;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniGetOpecvHOGRet(JNIEnv* env,
        jobject thiz, jobject detRet, jint index)
{
    if (mOpencvHOGDetctor) {
        cv::Rect rect = mOpencvHOGDetctor->getResult()[index];
        env->SetIntField(detRet, gVisionDetRetOffsets.left, rect.x);
        env->SetIntField(detRet, gVisionDetRetOffsets.top, rect.y);
        env->SetIntField(detRet, gVisionDetRetOffsets.right, rect.x + rect.width);
        env->SetIntField(detRet, gVisionDetRetOffsets.bottom, rect.y + rect.height);
        env->SetFloatField(detRet, gVisionDetRetOffsets.confidence, 0);
        jstring jstr=(jstring)(env->NewStringUTF("person"));
        env->SetObjectField(detRet, gVisionDetRetOffsets.label, (jobject)jstr);
        return 0;
    }
    return -1;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniDLibHOGDetect(
        JNIEnv* env, jobject thiz, jstring imgPath, jobject detRet)
{
    LOGD("com_tzutalin_dlib_PeopleDet jniDLibHOGDetect");
    const char *img_path = env->GetStringUTFChars(imgPath, 0);
    if(mDlibFaceDetector == NULL)
        mDlibFaceDetector = new DLibHOGFaceDetector();

    int size = mDlibFaceDetector->det(std::string(img_path));
    env->ReleaseStringUTFChars(imgPath, img_path);
    return size;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniGetDLibRet(JNIEnv* env,
        jobject thiz, jobject detRet, jint index)
{
    if (mDlibFaceDetector) {
        dlib::rectangle rect = mDlibFaceDetector->getResult()[index];
        env->SetIntField(detRet, gVisionDetRetOffsets.left, rect.left());
        env->SetIntField(detRet, gVisionDetRetOffsets.top, rect.top());
        env->SetIntField(detRet, gVisionDetRetOffsets.right, rect.right());
        env->SetIntField(detRet, gVisionDetRetOffsets.bottom, rect.bottom());
        env->SetFloatField(detRet, gVisionDetRetOffsets.confidence, 0);
        jstring jstr=(jstring)(env->NewStringUTF("face"));
        env->SetObjectField(detRet, gVisionDetRetOffsets.label, (jobject)jstr);
        return 0;
    }
    return -1;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniInit(JNIEnv* env, jobject thiz)
{

    if(mDlibFaceDetector == NULL)
        mDlibFaceDetector = new DLibHOGFaceDetector();

    if (mOpencvHOGDetctor == NULL)
        mOpencvHOGDetctor = new OpencvHOGDetctor();

    return 0;
}

jint JNIEXPORT JNICALL
Java_com_tzutalin_dlib_PeopleDet_jniDeInit(JNIEnv* env, jobject thiz)
{
    if(mDlibFaceDetector)
        delete mDlibFaceDetector;

    if (mOpencvHOGDetctor)
        delete mOpencvHOGDetctor;

    return 0;
}

#ifdef __cplusplus
}
#endif
<|endoftext|>


<commit_before>/*! \file helpers.hpp
    \brief Internal helper functionality
    \ingroup Internal */
/*
  Copyright (c) 2013, Randolph Voorhies, Shane Grant
  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 cereal 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 RANDOLPH VOORHIES OR SHANE GRANT 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.
*/
#ifndef CEREAL_DETAILS_HELPERS_HPP_
#define CEREAL_DETAILS_HELPERS_HPP_

#include <type_traits>
#include <cstdint>
#include <utility>

namespace cereal
{

  //! The size type used by cereal
  /*! To ensure compatability between 32, 64, etc bit machines, we need to use
   * a fixed size type instead of size_t, which may vary from machine to
   * machine. */
  typedef uint64_t size_type;

  // forward decls
  class BinaryOutputArchive;
  class BinaryInputArchive;

  // ######################################################################
  namespace detail
  {
    struct NameValuePairCore {};
  }

  //! For holding name value pairs
  /*! This pairs a name (some string) with some value such that an archive
      can potentially take advantage of the pairing.

      In serialization functions, NameValuePairs are usually created like so:
      @code{.cpp}
      struct MyStruct
      {
        int a, b, c, d, e;

        template<class Archive>
        void serialize(Archive & archive)
        {
          archive( CEREAL_NVP(a),
                   CEREAL_NVP(b),
                   CEREAL_NVP(c),
                   CEREAL_NVP(d),
                   CEREAL_NVP(e) );
        }
      };
      @endcode

      Alternatively, you can give you data members custom names like so:
      @code{.cpp}
      struct MyStruct
      {
        int a, b, my_embarrassing_variable_name, d, e;

        template<class Archive>
        void serialize(Archive & archive)
        {
          archive( CEREAL_NVP(a),
                   CEREAL_NVP(b),
                   cereal::make_nvp("var", my_embarrassing_variable_name) );
                   CEREAL_NVP(d),
                   CEREAL_NVP(e) );
        }
      };
      @endcode

      There is a slight amount of overhead to creating NameValuePairs, so there
      is a third method which will elide the names when they are not needed by
      the Archive:

      @code{.cpp}
      struct MyStruct
      {
        int a, b;

        template<class Archive>
        void serialize(Archive & archive)
        {
          archive( cereal::make_nvp<Archive>(a),
                   cereal::make_nvp<Archive>(b) );
        }
      };
      @endcode

      This third method is generally only used when providing generic type
      support.  Users writing their own serialize functions will normally
      explicitly control whether they want to use NVPs or not.

      @internal */
  template <class T>
  class NameValuePair : detail::NameValuePairCore
  {
    private:
      // If we get passed an RValue, we'll just make a local copy if it here
      // otherwise, we store a reference
      typedef typename std::decay<T>::type DT;
      typedef typename std::conditional<std::is_rvalue_reference<T>::value,
                                        DT,
                                        typename std::add_lvalue_reference<DT>::type>::type Type;
      // prevent nested nvps
      static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
                     "Cannot pair a name to a NameValuePair" );

    public:
      //! Constructs a new NameValuePair
      /*! @param n The name of the pair
          @param v The value to pair.  Ideally this should be an l-value reference so that
                   the value can be both loaded and saved to.  If you pass an r-value reference,
                   the NameValuePair will store a copy of it instead of a reference.  Thus you should
                   only pass r-values in cases where this makes sense, such as the result of some
                   size() call.  In either case, any constness will be stripped away
      @internal */
      NameValuePair( char const * n, T && v ) : name(n), value(const_cast<Type>(v)) {}

      char const * name;
      Type value;
  };

  //! A specialization of make_nvp<> that simply forwards the value for binary archives
  /*! @relates NameValuePair
      @internal */
  template<class Archive, class T> inline
  typename
  std::enable_if<std::is_same<Archive, ::cereal::BinaryInputArchive>::value ||
                 std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
  T && >::type
  make_nvp( const char *, T && value )
  {
    return std::forward<T>(value);
  }

  //! A specialization of make_nvp<> that actually creates an nvp for non-binary archives
  /*! @relates NameValuePair
      @internal */
  template<class Archive, class T> inline
  typename
  std::enable_if<!std::is_same<Archive, ::cereal::BinaryInputArchive>::value &&
                 !std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
  NameValuePair<T> >::type
  make_nvp( const char * name, T && value)
  {
    return {name, std::forward<T>(value)};
  }

  //! Convenience for creating a templated NVP
  /*! For use in inteneral generic typing functions which have an
      Archive type declared
      @internal */
#define _CEREAL_NVP(name, value) ::cereal::make_nvp<Archive>(name, value)

  // ######################################################################
  //! A wrapper around data that can be serialized in a binary fashion
  /*! This class is used to demarcate data that can safely be serialized
      as a binary chunk of data.  Individual archives can then choose how
      best represent this during serialization.

      @internal */
  template <class T>
  struct BinaryData
  {
    //! Internally store the pointer as a void *, keeping const if created with
    //! a const pointer
    typedef typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
                                      const void *,
                                      void *>::type PT;

    BinaryData( T && d, uint64_t s ) : data(d), size(s) {}

    PT data;   //!< pointer to beginning of data
    uint64_t size; //!< size in bytes
  };

  // ######################################################################
  namespace detail
  {
    // base classes for type checking
    struct OutputArchiveBase {};
    struct InputArchiveBase {};

    // forward decls for polymorphic support
    template <class Archive, class T> struct polymorphic_serialization_support;
    struct adl_tag;

    // used during saving pointers
    static const int32_t msb_32bit = 0x80000000;
    static const int32_t msb2_32bit = 0x40000000;
  }

  // ######################################################################
  //! A wrapper around size metadata
  /*! This class provides a way for archives to have more flexibility over how
      they choose to serialize size metadata for containers.  For some archive
      types, the size may be implicitly encoded in the output (e.g. JSON) and
      not need an explicit entry.  Specializing serialize or load/save for
      your archive and SizeTags allows you to choose what happens.

      @internal */
  template <class T>
  class SizeTag
  {
    private:
      // If we get passed an RValue, we'll just make a local copy if it here
      // otherwise, we store a reference
      typedef typename std::decay<T>::type DT;
      typedef typename std::conditional<std::is_rvalue_reference<T>::value,
                                        DT,
                                        typename std::add_lvalue_reference<DT>::type>::type Type;

    public:
      SizeTag( T && sz ) : size(const_cast<Type>(sz)) {}

      Type size;
  };

  // ######################################################################
  //! A wrapper around a key and value for serializing data into maps.
  /*! This class just provides a grouping of keys and values into a struct for
      human readable archives. For example, XML archives will use this wrapper
      to write maps like so:

      @code{.xml}
      <mymap>
        <item0>
          <key>MyFirstKey</key>
          <value>MyFirstValue</value>
        </item0>
        <item1>
          <key>MySecondKey</key>
          <value>MySecondValue</value>
        </item1>
      </mymap>
      @endcode

      \sa make_map_item
      @internal */
  template <class Key, class Value>
  struct MapItem
  {
    typedef typename std::decay<Key>::type DecayKey;
    typedef typename std::conditional<
      std::is_rvalue_reference<Key>::value,
      DecayKey,
      typename std::add_lvalue_reference<DecayKey>::type>::type KeyType;

    typedef typename std::decay<Value>::type DecayValue;
    typedef typename std::conditional<
      std::is_rvalue_reference<Value>::value,
      DecayValue,
      typename std::add_lvalue_reference<DecayValue>::type>::type ValueType;

    //! Construct a MapItem from a key and a value
    /*! @internal */
    MapItem( Key && key, Value && value ) : key(const_cast<KeyType>(key)), value(const_cast<ValueType>(value)) {}

    KeyType key;
    ValueType value;

    //! Serialize the MapItem with the NVPs "key" and "value"
    template <class Archive> inline
    void serialize(Archive & archive)
    {
      archive( make_nvp<Archive>("key",   key),
               make_nvp<Archive>("value", value) );
    }
  };

  //! Create a MapItem so that human readable archives will group keys and values together
  /*! @internal
      @relates MapItem */
  template <class KeyType, class ValueType> inline
  MapItem<KeyType, ValueType> make_map_item(KeyType && key, ValueType && value)
  {
    return {std::forward<KeyType>(key), std::forward<ValueType>(value)};
  }
} // namespace cereal

#endif // CEREAL_DETAILS_HELPERS_HPP_
<commit_msg>Fixes #27<commit_after>/*! \file helpers.hpp
    \brief Internal helper functionality
    \ingroup Internal */
/*
  Copyright (c) 2013, Randolph Voorhies, Shane Grant
  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 cereal 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 RANDOLPH VOORHIES OR SHANE GRANT 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.
*/
#ifndef CEREAL_DETAILS_HELPERS_HPP_
#define CEREAL_DETAILS_HELPERS_HPP_

#include <type_traits>
#include <cstdint>
#include <utility>

namespace cereal
{

  //! The size type used by cereal
  /*! To ensure compatability between 32, 64, etc bit machines, we need to use
   * a fixed size type instead of size_t, which may vary from machine to
   * machine. */
  typedef uint64_t size_type;

  // forward decls
  class BinaryOutputArchive;
  class BinaryInputArchive;

  // ######################################################################
  namespace detail
  {
    struct NameValuePairCore {};
  }

  //! For holding name value pairs
  /*! This pairs a name (some string) with some value such that an archive
      can potentially take advantage of the pairing.

      In serialization functions, NameValuePairs are usually created like so:
      @code{.cpp}
      struct MyStruct
      {
        int a, b, c, d, e;

        template<class Archive>
        void serialize(Archive & archive)
        {
          archive( CEREAL_NVP(a),
                   CEREAL_NVP(b),
                   CEREAL_NVP(c),
                   CEREAL_NVP(d),
                   CEREAL_NVP(e) );
        }
      };
      @endcode

      Alternatively, you can give you data members custom names like so:
      @code{.cpp}
      struct MyStruct
      {
        int a, b, my_embarrassing_variable_name, d, e;

        template<class Archive>
        void serialize(Archive & archive)
        {
          archive( CEREAL_NVP(a),
                   CEREAL_NVP(b),
                   cereal::make_nvp("var", my_embarrassing_variable_name) );
                   CEREAL_NVP(d),
                   CEREAL_NVP(e) );
        }
      };
      @endcode

      There is a slight amount of overhead to creating NameValuePairs, so there
      is a third method which will elide the names when they are not needed by
      the Archive:

      @code{.cpp}
      struct MyStruct
      {
        int a, b;

        template<class Archive>
        void serialize(Archive & archive)
        {
          archive( cereal::make_nvp<Archive>(a),
                   cereal::make_nvp<Archive>(b) );
        }
      };
      @endcode

      This third method is generally only used when providing generic type
      support.  Users writing their own serialize functions will normally
      explicitly control whether they want to use NVPs or not.

      @internal */
  template <class T>
  class NameValuePair : detail::NameValuePairCore
  {
    private:
      // If we get passed an RValue, we'll just make a local copy if it here
      // otherwise, we store a reference.  If we were passed an array, don't
      // decay the type - keep it as an array, and then proceed as normal
      // with the RValue business
      typedef typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
                                        typename std::remove_cv<T>::type,
                                        typename std::decay<T>::type>::type DT;
      typedef typename std::conditional<std::is_rvalue_reference<T>::value,
                                        DT,
                                        typename std::add_lvalue_reference<DT>::type>::type Type;
      // prevent nested nvps
      static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
                     "Cannot pair a name to a NameValuePair" );

    public:
      //! Constructs a new NameValuePair
      /*! @param n The name of the pair
          @param v The value to pair.  Ideally this should be an l-value reference so that
                   the value can be both loaded and saved to.  If you pass an r-value reference,
                   the NameValuePair will store a copy of it instead of a reference.  Thus you should
                   only pass r-values in cases where this makes sense, such as the result of some
                   size() call.  In either case, any constness will be stripped away
      @internal */
      NameValuePair( char const * n, T && v ) : name(n), value(const_cast<Type>(v)) {}

      char const * name;
      Type value;
  };

  //! A specialization of make_nvp<> that simply forwards the value for binary archives
  /*! @relates NameValuePair
      @internal */
  template<class Archive, class T> inline
  typename
  std::enable_if<std::is_same<Archive, ::cereal::BinaryInputArchive>::value ||
                 std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
  T && >::type
  make_nvp( const char *, T && value )
  {
    return std::forward<T>(value);
  }

  //! A specialization of make_nvp<> that actually creates an nvp for non-binary archives
  /*! @relates NameValuePair
      @internal */
  template<class Archive, class T> inline
  typename
  std::enable_if<!std::is_same<Archive, ::cereal::BinaryInputArchive>::value &&
                 !std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
  NameValuePair<T> >::type
  make_nvp( const char * name, T && value)
  {
    return {name, std::forward<T>(value)};
  }

  //! Convenience for creating a templated NVP
  /*! For use in inteneral generic typing functions which have an
      Archive type declared
      @internal */
#define _CEREAL_NVP(name, value) ::cereal::make_nvp<Archive>(name, value)

  // ######################################################################
  //! A wrapper around data that can be serialized in a binary fashion
  /*! This class is used to demarcate data that can safely be serialized
      as a binary chunk of data.  Individual archives can then choose how
      best represent this during serialization.

      @internal */
  template <class T>
  struct BinaryData
  {
    //! Internally store the pointer as a void *, keeping const if created with
    //! a const pointer
    typedef typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
                                      const void *,
                                      void *>::type PT;

    BinaryData( T && d, uint64_t s ) : data(d), size(s) {}

    PT data;   //!< pointer to beginning of data
    uint64_t size; //!< size in bytes
  };

  // ######################################################################
  namespace detail
  {
    // base classes for type checking
    struct OutputArchiveBase {};
    struct InputArchiveBase {};

    // forward decls for polymorphic support
    template <class Archive, class T> struct polymorphic_serialization_support;
    struct adl_tag;

    // used during saving pointers
    static const int32_t msb_32bit = 0x80000000;
    static const int32_t msb2_32bit = 0x40000000;
  }

  // ######################################################################
  //! A wrapper around size metadata
  /*! This class provides a way for archives to have more flexibility over how
      they choose to serialize size metadata for containers.  For some archive
      types, the size may be implicitly encoded in the output (e.g. JSON) and
      not need an explicit entry.  Specializing serialize or load/save for
      your archive and SizeTags allows you to choose what happens.

      @internal */
  template <class T>
  class SizeTag
  {
    private:
      // If we get passed an RValue, we'll just make a local copy if it here
      // otherwise, we store a reference
      typedef typename std::decay<T>::type DT;
      typedef typename std::conditional<std::is_rvalue_reference<T>::value,
                                        DT,
                                        typename std::add_lvalue_reference<DT>::type>::type Type;

    public:
      SizeTag( T && sz ) : size(const_cast<Type>(sz)) {}

      Type size;
  };

  // ######################################################################
  //! A wrapper around a key and value for serializing data into maps.
  /*! This class just provides a grouping of keys and values into a struct for
      human readable archives. For example, XML archives will use this wrapper
      to write maps like so:

      @code{.xml}
      <mymap>
        <item0>
          <key>MyFirstKey</key>
          <value>MyFirstValue</value>
        </item0>
        <item1>
          <key>MySecondKey</key>
          <value>MySecondValue</value>
        </item1>
      </mymap>
      @endcode

      \sa make_map_item
      @internal */
  template <class Key, class Value>
  struct MapItem
  {
    typedef typename std::decay<Key>::type DecayKey;
    typedef typename std::conditional<
      std::is_rvalue_reference<Key>::value,
      DecayKey,
      typename std::add_lvalue_reference<DecayKey>::type>::type KeyType;

    typedef typename std::decay<Value>::type DecayValue;
    typedef typename std::conditional<
      std::is_rvalue_reference<Value>::value,
      DecayValue,
      typename std::add_lvalue_reference<DecayValue>::type>::type ValueType;

    //! Construct a MapItem from a key and a value
    /*! @internal */
    MapItem( Key && key, Value && value ) : key(const_cast<KeyType>(key)), value(const_cast<ValueType>(value)) {}

    KeyType key;
    ValueType value;

    //! Serialize the MapItem with the NVPs "key" and "value"
    template <class Archive> inline
    void serialize(Archive & archive)
    {
      archive( make_nvp<Archive>("key",   key),
               make_nvp<Archive>("value", value) );
    }
  };

  //! Create a MapItem so that human readable archives will group keys and values together
  /*! @internal
      @relates MapItem */
  template <class KeyType, class ValueType> inline
  MapItem<KeyType, ValueType> make_map_item(KeyType && key, ValueType && value)
  {
    return {std::forward<KeyType>(key), std::forward<ValueType>(value)};
  }
} // namespace cereal

#endif // CEREAL_DETAILS_HELPERS_HPP_
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*!
 * \file type_relations.cc
 * \brief A set of utilities and common functionality
 * for type relations.
 */
#include "./type_relations.h"

#include <tvm/arith/analyzer.h>
#include <tvm/relay/attrs/transform.h>
#include <tvm/relay/expr.h>
#include <tvm/relay/op.h>
#include <tvm/tir/op.h>

#include <numeric>

namespace tvm {
namespace relay {

bool IdentityRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                 const TypeReporter& reporter) {
  for (size_t i = 1; i < types.size(); ++i) {
    reporter->Assign(types[i], types[0]);
  }
  return true;
}

bool EqualCheck(const IndexExpr& lhs, const IndexExpr& rhs) {
  IndexExpr diff = lhs - rhs;
  if (const int64_t* pdiff = tir::as_const_int(diff)) {
    return pdiff[0] == 0;
  }
  // symbolic
  tvm::arith::Analyzer ana;
  diff = ana.Simplify(diff);
  if (const int64_t* pdiff = tir::as_const_int(diff)) {
    return pdiff[0] == 0;
  }
  return false;
}

bool EqualConstInt(const IndexExpr& lhs, int64_t value) {
  if (const int64_t* pvalue = tir::as_const_int(lhs)) {
    return pvalue[0] == value;
  }
  return false;
}

TensorType ConcreteBroadcast(const TensorType& t1, const TensorType& t2, DataType output_dtype) {
  std::vector<IndexExpr> oshape;
  size_t ndim1 = t1->shape.size();
  size_t ndim2 = t2->shape.size();
  size_t i = 1;
  for (; i <= std::min(ndim1, ndim2); ++i) {
    IndexExpr s1 = t1->shape[ndim1 - i];
    IndexExpr s2 = t2->shape[ndim2 - i];
    if (EqualConstInt(s1, 1)) {
      oshape.push_back(s2);
    } else if (EqualConstInt(s2, 1)) {
      oshape.push_back(s1);
    } else if (s1.as<AnyNode>()) {
      // s1 == 1 || s1 == s2
      oshape.push_back(s2);
    } else if (s2.as<AnyNode>()) {
      // s2 == 1 || s2 == s1
      oshape.push_back(s1);
    } else if (EqualCheck(s1, s2)) {
      oshape.push_back(s1);
    } else {
      throw CompileError(ErrorBuilder() << "Incompatible broadcast type " << t1 << " and " << t2);
    }
  }

  size_t max_ndim = std::max(ndim1, ndim2);
  auto& rshape = (ndim1 > ndim2) ? t1->shape : t2->shape;
  for (; i <= max_ndim; ++i) {
    oshape.push_back(rshape[max_ndim - i]);
  }
  return TensorType(Array<IndexExpr>(oshape.rbegin(), oshape.rend()), output_dtype);
}

bool BroadcastRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                  const TypeReporter& reporter) {
  ICHECK_EQ(types.size(), 3);
  // DLOG(INFO) << "In1:" << types[0] << ",In2:" << types[1]
  //                 << ",Out:" << types[2] << std::endl;
  if (auto* t0 = types[0].as<TensorTypeNode>()) {
    if (auto* t1 = types[1].as<TensorTypeNode>()) {
      if (t0->dtype != t1->dtype) {
        reporter->GetDiagCtx().Emit(Diagnostic::Error(t0->span)
                                    << "data types " << t0->dtype << " and " << t1->dtype
                                    << "do not match in BroadcastRel");
      }
      reporter->Assign(
          types[2], ConcreteBroadcast(GetRef<TensorType>(t0), GetRef<TensorType>(t1), t0->dtype));
      return true;
    }
  }
  return false;
}

bool BroadcastCompRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                      const TypeReporter& reporter) {
  ICHECK_EQ(types.size(), 3);
  // DLOG(INFO) << "In1:" << types[0] << ",In2:" << types[1]
  //                 << ",Out:" << types[2] << std::endl;
  if (auto* t0 = types[0].as<TensorTypeNode>()) {
    if (auto* t1 = types[1].as<TensorTypeNode>()) {
      if (t0->dtype != t1->dtype) {
        reporter->GetDiagCtx().Emit(Diagnostic::Error(t0->span)
                                    << "data types " << t0->dtype << " and " << t1->dtype
                                    << "do not match in BroadcastCompRel");
      }
      reporter->Assign(types[2], ConcreteBroadcast(GetRef<TensorType>(t0), GetRef<TensorType>(t1),
                                                   DataType::Bool()));
      return true;
    }
  }
  return false;
}

bool IdentityCompRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                     const TypeReporter& reporter) {
  if (auto* t0 = types[0].as<TensorTypeNode>()) {
    Type out_type = TensorType(GetRef<TensorType>(t0)->shape, DataType::Bool());
    reporter->Assign(types[1], out_type);
    return true;
  }
  return false;
}

Array<IndexExpr> RankShape(const Array<IndexExpr>& shape) {
  if (shape.size() == 0) {
    return {};
  } else {
    return {tvm::Integer(shape.size())};
  }
}

bool ShapeOfRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                const TypeReporter& reporter) {
  ICHECK_EQ(num_inputs, 1);
  auto tt = types[0].as<TensorTypeNode>();
  if (tt == nullptr) {
    return false;
  }
  const auto* param = attrs.as<ShapeOfAttrs>();
  ICHECK(param != nullptr);
  auto rank_shape = RankShape(tt->shape);
  reporter->Assign(types[1], TensorType(rank_shape, param->dtype));
  return true;
}

}  // namespace relay
}  // namespace tvm
<commit_msg>Add one extra space to improve diagnostic messages (#10268)<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*!
 * \file type_relations.cc
 * \brief A set of utilities and common functionality
 * for type relations.
 */
#include "./type_relations.h"

#include <tvm/arith/analyzer.h>
#include <tvm/relay/attrs/transform.h>
#include <tvm/relay/expr.h>
#include <tvm/relay/op.h>
#include <tvm/tir/op.h>

#include <numeric>

namespace tvm {
namespace relay {

bool IdentityRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                 const TypeReporter& reporter) {
  for (size_t i = 1; i < types.size(); ++i) {
    reporter->Assign(types[i], types[0]);
  }
  return true;
}

bool EqualCheck(const IndexExpr& lhs, const IndexExpr& rhs) {
  IndexExpr diff = lhs - rhs;
  if (const int64_t* pdiff = tir::as_const_int(diff)) {
    return pdiff[0] == 0;
  }
  // symbolic
  tvm::arith::Analyzer ana;
  diff = ana.Simplify(diff);
  if (const int64_t* pdiff = tir::as_const_int(diff)) {
    return pdiff[0] == 0;
  }
  return false;
}

bool EqualConstInt(const IndexExpr& lhs, int64_t value) {
  if (const int64_t* pvalue = tir::as_const_int(lhs)) {
    return pvalue[0] == value;
  }
  return false;
}

TensorType ConcreteBroadcast(const TensorType& t1, const TensorType& t2, DataType output_dtype) {
  std::vector<IndexExpr> oshape;
  size_t ndim1 = t1->shape.size();
  size_t ndim2 = t2->shape.size();
  size_t i = 1;
  for (; i <= std::min(ndim1, ndim2); ++i) {
    IndexExpr s1 = t1->shape[ndim1 - i];
    IndexExpr s2 = t2->shape[ndim2 - i];
    if (EqualConstInt(s1, 1)) {
      oshape.push_back(s2);
    } else if (EqualConstInt(s2, 1)) {
      oshape.push_back(s1);
    } else if (s1.as<AnyNode>()) {
      // s1 == 1 || s1 == s2
      oshape.push_back(s2);
    } else if (s2.as<AnyNode>()) {
      // s2 == 1 || s2 == s1
      oshape.push_back(s1);
    } else if (EqualCheck(s1, s2)) {
      oshape.push_back(s1);
    } else {
      throw CompileError(ErrorBuilder() << "Incompatible broadcast type " << t1 << " and " << t2);
    }
  }

  size_t max_ndim = std::max(ndim1, ndim2);
  auto& rshape = (ndim1 > ndim2) ? t1->shape : t2->shape;
  for (; i <= max_ndim; ++i) {
    oshape.push_back(rshape[max_ndim - i]);
  }
  return TensorType(Array<IndexExpr>(oshape.rbegin(), oshape.rend()), output_dtype);
}

bool BroadcastRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                  const TypeReporter& reporter) {
  ICHECK_EQ(types.size(), 3);
  // DLOG(INFO) << "In1:" << types[0] << ",In2:" << types[1]
  //                 << ",Out:" << types[2] << std::endl;
  if (auto* t0 = types[0].as<TensorTypeNode>()) {
    if (auto* t1 = types[1].as<TensorTypeNode>()) {
      if (t0->dtype != t1->dtype) {
        reporter->GetDiagCtx().Emit(Diagnostic::Error(t0->span)
                                    << "data types " << t0->dtype << " and " << t1->dtype
                                    << " do not match in BroadcastRel");
      }
      reporter->Assign(
          types[2], ConcreteBroadcast(GetRef<TensorType>(t0), GetRef<TensorType>(t1), t0->dtype));
      return true;
    }
  }
  return false;
}

bool BroadcastCompRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                      const TypeReporter& reporter) {
  ICHECK_EQ(types.size(), 3);
  // DLOG(INFO) << "In1:" << types[0] << ",In2:" << types[1]
  //                 << ",Out:" << types[2] << std::endl;
  if (auto* t0 = types[0].as<TensorTypeNode>()) {
    if (auto* t1 = types[1].as<TensorTypeNode>()) {
      if (t0->dtype != t1->dtype) {
        reporter->GetDiagCtx().Emit(Diagnostic::Error(t0->span)
                                    << "data types " << t0->dtype << " and " << t1->dtype
                                    << " do not match in BroadcastCompRel");
      }
      reporter->Assign(types[2], ConcreteBroadcast(GetRef<TensorType>(t0), GetRef<TensorType>(t1),
                                                   DataType::Bool()));
      return true;
    }
  }
  return false;
}

bool IdentityCompRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                     const TypeReporter& reporter) {
  if (auto* t0 = types[0].as<TensorTypeNode>()) {
    Type out_type = TensorType(GetRef<TensorType>(t0)->shape, DataType::Bool());
    reporter->Assign(types[1], out_type);
    return true;
  }
  return false;
}

Array<IndexExpr> RankShape(const Array<IndexExpr>& shape) {
  if (shape.size() == 0) {
    return {};
  } else {
    return {tvm::Integer(shape.size())};
  }
}

bool ShapeOfRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                const TypeReporter& reporter) {
  ICHECK_EQ(num_inputs, 1);
  auto tt = types[0].as<TensorTypeNode>();
  if (tt == nullptr) {
    return false;
  }
  const auto* param = attrs.as<ShapeOfAttrs>();
  ICHECK(param != nullptr);
  auto rank_shape = RankShape(tt->shape);
  reporter->Assign(types[1], TensorType(rank_shape, param->dtype));
  return true;
}

}  // namespace relay
}  // namespace tvm
<|endoftext|>


<commit_before>// Copyright 2016 Google Inc. All rights reserved
//
// 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.

// +build ignore

// This command will dump the contents of a kati stamp file into a more portable
// format for use by other tools. For now, it just exports the files read.
// Later, this will be expanded to include the Glob and Shell commands, but
// those require a more complicated output format.

#include <stdio.h>

#include <string>

#include "io.h"
#include "log.h"
#include "strutil.h"

int main(int argc, char* argv[]) {
  if (argc == 1) {
    fprintf(stderr, "Usage: ckati_stamp_dump <stamp>\n");
    return 1;
  }

  FILE *fp = fopen(argv[1], "rb");
  if(!fp)
    PERROR("fopen");

  ScopedFile sfp(fp);
  double gen_time;
  size_t r = fread(&gen_time, sizeof(gen_time), 1, fp);
  if (r != 1)
    ERROR("Incomplete stamp file");

  int num_files = LoadInt(fp);
  if (num_files < 0)
    ERROR("Incomplete stamp file");
  for (int i = 0; i < num_files; i++) {
    string s;
    if (!LoadString(fp, s))
      ERROR("Incomplete stamp file");
    printf("%s\n", s.c_str());
  }

  return 0;
}
<commit_msg>Fix typo in regen_dump.cc<commit_after>// Copyright 2016 Google Inc. All rights reserved
//
// 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.

// +build ignore

// This command will dump the contents of a kati stamp file into a more portable
// format for use by other tools. For now, it just exports the files read.
// Later, this will be expanded to include the Glob and Shell commands, but
// those require a more complicated output format.

#include <stdio.h>

#include <string>

#include "io.h"
#include "log.h"
#include "strutil.h"

int main(int argc, char* argv[]) {
  if (argc == 1) {
    fprintf(stderr, "Usage: ckati_stamp_dump <stamp>\n");
    return 1;
  }

  FILE *fp = fopen(argv[1], "rb");
  if(!fp)
    PERROR("fopen");

  ScopedFile sfp(fp);
  double gen_time;
  size_t r = fread(&gen_time, sizeof(gen_time), 1, fp);
  if (r != 1)
    ERROR("Incomplete stamp file");

  int num_files = LoadInt(fp);
  if (num_files < 0)
    ERROR("Incomplete stamp file");
  for (int i = 0; i < num_files; i++) {
    string s;
    if (!LoadString(fp, &s))
      ERROR("Incomplete stamp file");
    printf("%s\n", s.c_str());
  }

  return 0;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_ICU_SHAPER_HPP
#define MAPNIK_ICU_SHAPER_HPP

// mapnik
#include <mapnik/text/text_properties.hpp>
#include <mapnik/text/text_line.hpp>
#include <mapnik/text/face.hpp>
#include <mapnik/debug.hpp>

// stl
#include <list>

// icu
#include <unicode/unistr.h>
#include <unicode/ushape.h>
#include <unicode/schriter.h>

namespace mapnik
{

struct icu_shaper
{
static void shape_text(text_line & line,
                       text_itemizer & itemizer,
                       std::map<unsigned,double> & width_map,
                       face_manager_freetype & font_manager,
                       double scale_factor )
{
    unsigned start = line.first_char();
    unsigned end = line.last_char();
    size_t length = end - start;
    if (!length) return;
    line.reserve(length);
    std::list<text_item> const& list = itemizer.itemize(start, end);
    mapnik::value_unicode_string const& text = itemizer.text();
    UErrorCode err = U_ZERO_ERROR;
    mapnik::value_unicode_string shaped;
    mapnik::value_unicode_string reordered;
    unsigned char_index = 0;

    for (auto const& text_item : list)
    {
        face_set_ptr face_set = font_manager.get_face_set(text_item.format->face_name, text_item.format->fontset);
        double size = text_item.format->text_size * scale_factor;
        face_set->set_unscaled_character_sizes();
        for (auto const& face : *face_set)
        {

            UBiDi *bidi = ubidi_openSized(length, 0, &err);
            ubidi_setPara(bidi, text.getBuffer() + start, length, UBIDI_DEFAULT_LTR, 0, &err);
            ubidi_writeReordered(bidi, reordered.getBuffer(length),
                                 length, UBIDI_DO_MIRRORING, &err);
            ubidi_close(bidi);
            reordered.releaseBuffer(length);

            int32_t num_char = u_shapeArabic(reordered.getBuffer(), length,
                                             shaped.getBuffer(length), length,
                                             U_SHAPE_LETTERS_SHAPE | U_SHAPE_LENGTH_FIXED_SPACES_NEAR |
                                             U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, &err);
            if (num_char < 0)
            {
                MAPNIK_LOG_ERROR(icu_shaper) << " u_shapeArabic returned negative num_char " << num_char;
            }
            std::size_t num_chars = static_cast<std::size_t>(num_char);
            shaped.releaseBuffer(length);
            bool shaped_status = true;
            if (U_SUCCESS(err) && (num_chars == length))
            {
                U_NAMESPACE_QUALIFIER StringCharacterIterator iter(shaped);
                for (iter.setToStart(); iter.hasNext();)
                {
                    UChar ch = iter.nextPostInc();
                    glyph_info tmp;
                    tmp.glyph_index = FT_Get_Char_Index(face->get_face(), ch);
                    tmp.offset.clear();
                    if (tmp.glyph_index == 0)
                    {
                        shaped_status = false;
                        break;
                    }
                    if (face->glyph_dimensions(tmp))
                    {
                        tmp.char_index = char_index;
                        tmp.face = face;
                        tmp.format = text_item.format;
                        tmp.scale_multiplier = size / face->get_face()->units_per_EM;
                        width_map[char_index++] += tmp.advance();
                        line.add_glyph(tmp, scale_factor);
                    }
                }
            }
            if (!shaped_status) continue;
            line.update_max_char_height(face->get_char_height(size));
            return;
        }
    }
}

};
} //namespace mapnik

#endif // MAPNIK_ICU_SHAPER_HPP
<commit_msg>itemizer should be const in icu_shaper<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_ICU_SHAPER_HPP
#define MAPNIK_ICU_SHAPER_HPP

// mapnik
#include <mapnik/text/text_properties.hpp>
#include <mapnik/text/text_line.hpp>
#include <mapnik/text/face.hpp>
#include <mapnik/debug.hpp>

// stl
#include <list>

// icu
#include <unicode/unistr.h>
#include <unicode/ushape.h>
#include <unicode/schriter.h>

namespace mapnik
{

struct icu_shaper
{
static void shape_text(text_line & line,
                       text_itemizer const& itemizer,
                       std::map<unsigned,double> & width_map,
                       face_manager_freetype & font_manager,
                       double scale_factor )
{
    unsigned start = line.first_char();
    unsigned end = line.last_char();
    size_t length = end - start;
    if (!length) return;
    line.reserve(length);
    std::list<text_item> const& list = itemizer.itemize(start, end);
    mapnik::value_unicode_string const& text = itemizer.text();
    UErrorCode err = U_ZERO_ERROR;
    mapnik::value_unicode_string shaped;
    mapnik::value_unicode_string reordered;
    unsigned char_index = 0;

    for (auto const& text_item : list)
    {
        face_set_ptr face_set = font_manager.get_face_set(text_item.format->face_name, text_item.format->fontset);
        double size = text_item.format->text_size * scale_factor;
        face_set->set_unscaled_character_sizes();
        for (auto const& face : *face_set)
        {

            UBiDi *bidi = ubidi_openSized(length, 0, &err);
            ubidi_setPara(bidi, text.getBuffer() + start, length, UBIDI_DEFAULT_LTR, 0, &err);
            ubidi_writeReordered(bidi, reordered.getBuffer(length),
                                 length, UBIDI_DO_MIRRORING, &err);
            ubidi_close(bidi);
            reordered.releaseBuffer(length);

            int32_t num_char = u_shapeArabic(reordered.getBuffer(), length,
                                             shaped.getBuffer(length), length,
                                             U_SHAPE_LETTERS_SHAPE | U_SHAPE_LENGTH_FIXED_SPACES_NEAR |
                                             U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, &err);
            if (num_char < 0)
            {
                MAPNIK_LOG_ERROR(icu_shaper) << " u_shapeArabic returned negative num_char " << num_char;
            }
            std::size_t num_chars = static_cast<std::size_t>(num_char);
            shaped.releaseBuffer(length);
            bool shaped_status = true;
            if (U_SUCCESS(err) && (num_chars == length))
            {
                U_NAMESPACE_QUALIFIER StringCharacterIterator iter(shaped);
                for (iter.setToStart(); iter.hasNext();)
                {
                    UChar ch = iter.nextPostInc();
                    glyph_info tmp;
                    tmp.glyph_index = FT_Get_Char_Index(face->get_face(), ch);
                    tmp.offset.clear();
                    if (tmp.glyph_index == 0)
                    {
                        shaped_status = false;
                        break;
                    }
                    if (face->glyph_dimensions(tmp))
                    {
                        tmp.char_index = char_index;
                        tmp.face = face;
                        tmp.format = text_item.format;
                        tmp.scale_multiplier = size / face->get_face()->units_per_EM;
                        width_map[char_index++] += tmp.advance();
                        line.add_glyph(tmp, scale_factor);
                    }
                }
            }
            if (!shaped_status) continue;
            line.update_max_char_height(face->get_char_height(size));
            return;
        }
    }
}

};
} //namespace mapnik

#endif // MAPNIK_ICU_SHAPER_HPP
<|endoftext|>


<commit_before>#pragma once
#include "dedisp.h"
#include <cstdlib>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <stdexcept>
#include <data_types/timeseries.hpp>
#include <data_types/filterbank.hpp>
#include <utils/exceptions.hpp>

class Dedisperser {
private:
  dedisp_plan plan;
  Filterbank& filterbank;
  unsigned int num_gpus;
  std::vector<float> dm_list;
  std::vector<dedisp_bool> killmask;

public:
  Dedisperser(Filterbank& filterbank, unsigned int num_gpus=1)
    :filterbank(filterbank), num_gpus(num_gpus)
  {
    killmask.resize(filterbank.get_nchans(),1);
    dedisp_error error = dedisp_create_plan_multi(&plan,
						  filterbank.get_nchans(),
						  filterbank.get_tsamp(),
						  filterbank.get_fch1(),
						  filterbank.get_foff(),
						  num_gpus);
    ErrorChecker::check_dedisp_error(error,"create_plan_multi");
  }

  virtual ~Dedisperser()
  {
    if( plan ) {
      dedisp_destroy_plan(plan);
    }
  }

  void set_dm_list(float* dm_list_ptr, unsigned int ndms)
  {
    dm_list.resize(ndms);
    std::copy(dm_list_ptr, dm_list_ptr+ndms, dm_list.begin());
    dedisp_error error = dedisp_set_dm_list(plan,&dm_list[0],dm_list.size());
    ErrorChecker::check_dedisp_error(error,"set_dm_list");
  }

  void set_dm_list(std::vector<float> dm_list_vec)
  {
    dm_list.resize(dm_list_vec.size());
    std::copy(dm_list_vec.begin(), dm_list_vec.end(), dm_list.begin());
    dedisp_error error = dedisp_set_dm_list(plan,&dm_list[0],dm_list.size());
    ErrorChecker::check_dedisp_error(error,"set_dm_list");
  }

  std::vector<float> get_dm_list(void){
    return dm_list;
  }

  void generate_dm_list(float dm_start, float dm_end,
			float width, float tolerance)
  {
    dedisp_error error = dedisp_generate_dm_list(plan, dm_start, dm_end, width, tolerance);
    ErrorChecker::check_dedisp_error(error,"generate_dm_list");
    dm_list.resize(dedisp_get_dm_count(plan));
    const float* plan_dm_list = dedisp_get_dm_list(plan);
    std::copy(plan_dm_list,plan_dm_list+dm_list.size(),dm_list.begin());
  }

  void set_killmask(std::vector<int> killmask_in)
  {
    killmask.swap(killmask_in);
    dedisp_error error = dedisp_set_killmask(plan,&killmask[0]);
    ErrorChecker::check_dedisp_error(error,"set_killmask");
  }

  void set_killmask(std::string filename)
  {
    std::ifstream infile;
    std::string str;
    killmask.clear();
    infile.open(filename.c_str(),std::ifstream::in | std::ifstream::binary);
    ErrorChecker::check_file_error(infile,filename);

    int ii=0;
    while(!infile.eof()&&ii<filterbank.get_nchans()){
      std::getline(infile, str);
      killmask.push_back(std::atoi(str.c_str()));
      ii++;
    }

    if (killmask.size() != filterbank.get_nchans()){
      std::cerr << "WARNING: killmask is not the same size as nchans" << std::endl;
      std::cerr << killmask.size() <<" != " <<  filterbank.get_nchans() <<  std::endl;
      killmask.resize(filterbank.get_nchans(),1);
    } else {
      dedisp_error error = dedisp_set_killmask(plan,&killmask[0]);
      ErrorChecker::check_dedisp_error(error,"set_killmask");
    }

  }

  void dedisperse(DispersionTrials<float>& trials,
                  std::size_t start_sample, std::size_t nsamps,
                  std::size_t gulp)
  {
    std::vector<float> temp_buffer;
    std::size_t max_delay = dedisp_get_max_delay(plan);
    std::cout << "Max DM delay: " << max_delay << std::endl;
    if (gulp < 2 * max_delay)
    {
      gulp = 2 * max_delay;
      std::cerr << "WARNING: Gulp size < 2 x maximum DM delay, adjusting gulp size to "
                << gulp << " bytes"<< std::endl;
    }

    if ((start_sample + nsamps) > filterbank.get_nsamps())
    {
      nsamps = filterbank.get_nsamps() - start_sample;
      std::cerr << "WARNING: Number of sample requested exceeds input filterbank length "
                << "revising to " << nsamps << " samples" << std::endl;
    }

    // Calculated the total number of output samples expected
    std::size_t total_out_nsamps = nsamps - max_delay;
    std::cout << "Total Dedisp output samples: " << total_out_nsamps << std::endl;

    // Create a complete trials object to contain all trials at full length
    //std::cout << "DM list size " << dm_list.size() << std::endl;
    //std::cout << "Trials pre size " << trials.get_data().size() << std::endl;
    //std::cout << "Count " << trials.get_count() << " nsamps " << trials.get_nsamps() << std::endl;
    trials.resize(total_out_nsamps, dm_list);
    //std::cout << "Trials post size " << trials.get_data().size() << std::endl;
    //std::cout << "Count " << trials.get_count() << " nsamps " << trials.get_nsamps() << std::endl;

    while (start_sample < total_out_nsamps)
    {
      std::cout << "Dedispersing samples " << start_sample
	        << " to " << start_sample + gulp << " of "
                << total_out_nsamps << std::endl;
      // Load a block of data from the filterbank
      std::size_t loaded_samples = filterbank.load_gulp(start_sample, gulp);

      // Calculate the expected number of output samples from a dedisp call
      std::size_t dedisp_samples = loaded_samples - max_delay;
      //std::cout << "Dedisp output samples from block: " << dedisp_samples << std::endl;

      // Calculate the actual number of samples to memcpy
      std::size_t nsamps_to_copy;
      if (dedisp_samples + start_sample > total_out_nsamps){
        nsamps_to_copy = total_out_nsamps - start_sample;
      } else {
 	nsamps_to_copy = dedisp_samples;
      }
      // Resize the temporary buffer to handle the output of the next dedisp call
      temp_buffer.resize(gulp * dm_list.size());

      // Run Dedisp with output into the temporary buffer
      //std::cout << "Calling Dedisp" << std::endl;
      dedisp_error error = dedisp_execute(plan,
          loaded_samples,
          filterbank.get_data(),  //This pointer gets set in the filterband.load_gulp method
          filterbank.get_nbits(),
          reinterpret_cast<unsigned char*>(temp_buffer.data()),
          32, // Float output
          (unsigned) 0);
      ErrorChecker::check_dedisp_error(error,"execute");

      // Get a pointer to the final trials data
      std::vector<float> const& data = trials.get_data();
      std::cout << "Trials total size: " << data.size() * sizeof(float) << " bytes" << std::endl;
      float* ptr = reinterpret_cast<float*>(trials.get_data_ptr());

      // Loop over the trials and for each take the data from the temporary buffer
      // and memcpy it into the correct location in the final trials object
      std::cout << "Performing transpose/merge of Dedisp output samples" << std::endl;

      for (std::size_t trial_idx = 0; trial_idx < dm_list.size(); ++trial_idx)
      {
        // Calculate destination offset for trails pointer
        //std::cout << "Trial IDx " << trial_idx << std::endl;
        std::size_t offset = total_out_nsamps * trial_idx + start_sample;
        //std::cout << "Offset " << offset << std::endl;
        //std::cout << "Temp offset " << dedisp_samples * trial_idx << std::endl;
        //std::cout << "Trials size " << trials.get_data().size() << std::endl;
        //std::cout << "Temp size " << temp_buffer.size() << std::endl;
        //std::cout << "nsamps to copy " << nsamps_to_copy << std::endl;

        //std::cout << "Dest offset: " << offset * sizeof(float)
        //          << " size: " << sizeof(float) * trials.get_count() * trials.get_nsamps()
        //          << " remaining: " << sizeof(float) * trials.get_count() * trials.get_nsamps() - offset * sizeof(float)
        //          << " to_copy: " << sizeof(float) * nsamps_to_copy << std::endl;

        std::memcpy( reinterpret_cast<char*>(ptr + offset),
                     reinterpret_cast<char*>(temp_buffer.data() + dedisp_samples * trial_idx),
                     sizeof(float) * nsamps_to_copy);
      }

      // Update the start_sample based on the number of samples output by dedisp
      start_sample += dedisp_samples;
      //std::cout << "Updating start sample to " << start_sample << std::endl;
    }

  }
};

<commit_msg>fixed zero read size loop bug<commit_after>#pragma once
#include "dedisp.h"
#include <cstdlib>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <stdexcept>
#include <data_types/timeseries.hpp>
#include <data_types/filterbank.hpp>
#include <utils/exceptions.hpp>

class Dedisperser {
private:
  dedisp_plan plan;
  Filterbank& filterbank;
  unsigned int num_gpus;
  std::vector<float> dm_list;
  std::vector<dedisp_bool> killmask;

public:
  Dedisperser(Filterbank& filterbank, unsigned int num_gpus=1)
    :filterbank(filterbank), num_gpus(num_gpus)
  {
    killmask.resize(filterbank.get_nchans(),1);
    dedisp_error error = dedisp_create_plan_multi(&plan,
						  filterbank.get_nchans(),
						  filterbank.get_tsamp(),
						  filterbank.get_fch1(),
						  filterbank.get_foff(),
						  num_gpus);
    ErrorChecker::check_dedisp_error(error,"create_plan_multi");
  }

  virtual ~Dedisperser()
  {
    if( plan ) {
      dedisp_destroy_plan(plan);
    }
  }

  void set_dm_list(float* dm_list_ptr, unsigned int ndms)
  {
    dm_list.resize(ndms);
    std::copy(dm_list_ptr, dm_list_ptr+ndms, dm_list.begin());
    dedisp_error error = dedisp_set_dm_list(plan,&dm_list[0],dm_list.size());
    ErrorChecker::check_dedisp_error(error,"set_dm_list");
  }

  void set_dm_list(std::vector<float> dm_list_vec)
  {
    dm_list.resize(dm_list_vec.size());
    std::copy(dm_list_vec.begin(), dm_list_vec.end(), dm_list.begin());
    dedisp_error error = dedisp_set_dm_list(plan,&dm_list[0],dm_list.size());
    ErrorChecker::check_dedisp_error(error,"set_dm_list");
  }

  std::vector<float> get_dm_list(void){
    return dm_list;
  }

  void generate_dm_list(float dm_start, float dm_end,
			float width, float tolerance)
  {
    dedisp_error error = dedisp_generate_dm_list(plan, dm_start, dm_end, width, tolerance);
    ErrorChecker::check_dedisp_error(error,"generate_dm_list");
    dm_list.resize(dedisp_get_dm_count(plan));
    const float* plan_dm_list = dedisp_get_dm_list(plan);
    std::copy(plan_dm_list,plan_dm_list+dm_list.size(),dm_list.begin());
  }

  void set_killmask(std::vector<int> killmask_in)
  {
    killmask.swap(killmask_in);
    dedisp_error error = dedisp_set_killmask(plan,&killmask[0]);
    ErrorChecker::check_dedisp_error(error,"set_killmask");
  }

  void set_killmask(std::string filename)
  {
    std::ifstream infile;
    std::string str;
    killmask.clear();
    infile.open(filename.c_str(),std::ifstream::in | std::ifstream::binary);
    ErrorChecker::check_file_error(infile,filename);

    int ii=0;
    while(!infile.eof()&&ii<filterbank.get_nchans()){
      std::getline(infile, str);
      killmask.push_back(std::atoi(str.c_str()));
      ii++;
    }

    if (killmask.size() != filterbank.get_nchans()){
      std::cerr << "WARNING: killmask is not the same size as nchans" << std::endl;
      std::cerr << killmask.size() <<" != " <<  filterbank.get_nchans() <<  std::endl;
      killmask.resize(filterbank.get_nchans(),1);
    } else {
      dedisp_error error = dedisp_set_killmask(plan,&killmask[0]);
      ErrorChecker::check_dedisp_error(error,"set_killmask");
    }

  }

  void dedisperse(DispersionTrials<float>& trials,
                  std::size_t start_sample, std::size_t nsamps,
                  std::size_t gulp)
  {
    std::vector<float> temp_buffer;
    std::size_t max_delay = dedisp_get_max_delay(plan);
    std::cout << "Max DM delay: " << max_delay << std::endl;
    if (gulp < 2 * max_delay)
    {
      gulp = 2 * max_delay;
      std::cerr << "WARNING: Gulp size < 2 x maximum DM delay, adjusting gulp size to "
                << gulp << " bytes"<< std::endl;
    }

    if ((start_sample + nsamps) > filterbank.get_nsamps())
    {
      nsamps = filterbank.get_nsamps() - start_sample;
      std::cerr << "WARNING: Number of sample requested exceeds input filterbank length "
                << "revising to " << nsamps << " samples" << std::endl;
    }

    // Calculated the total number of output samples expected
    std::size_t total_out_nsamps = nsamps - max_delay;
    std::cout << "Total Dedisp output samples: " << total_out_nsamps << std::endl;

    // Create a complete trials object to contain all trials at full length
    //std::cout << "DM list size " << dm_list.size() << std::endl;
    //std::cout << "Trials pre size " << trials.get_data().size() << std::endl;
    //std::cout << "Count " << trials.get_count() << " nsamps " << trials.get_nsamps() << std::endl;
    trials.resize(total_out_nsamps, dm_list);
    //std::cout << "Trials post size " << trials.get_data().size() << std::endl;
    //std::cout << "Count " << trials.get_count() << " nsamps " << trials.get_nsamps() << std::endl;

    while (start_sample < total_out_nsamps)
    {
      std::cout << "Dedispersing samples " << start_sample
	        << " to " << start_sample + gulp << " of "
                << total_out_nsamps << std::endl;
      // Load a block of data from the filterbank
      std::size_t loaded_samples = filterbank.load_gulp(start_sample, gulp);
      if (loaded_samples == 0)
      {
          throw std::runtime_error("Failure on reading data during dedispersion, 0 bytes read.");
      }

      // Calculate the expected number of output samples from a dedisp call
      std::size_t dedisp_samples = loaded_samples - max_delay;
      //std::cout << "Dedisp output samples from block: " << dedisp_samples << std::endl;

      // Calculate the actual number of samples to memcpy
      std::size_t nsamps_to_copy;
      if (dedisp_samples + start_sample > total_out_nsamps){
        nsamps_to_copy = total_out_nsamps - start_sample;
      } else {
 	nsamps_to_copy = dedisp_samples;
      }
      // Resize the temporary buffer to handle the output of the next dedisp call
      temp_buffer.resize(gulp * dm_list.size());

      // Run Dedisp with output into the temporary buffer
      //std::cout << "Calling Dedisp" << std::endl;
      dedisp_error error = dedisp_execute(plan,
          loaded_samples,
          filterbank.get_data(),  //This pointer gets set in the filterband.load_gulp method
          filterbank.get_nbits(),
          reinterpret_cast<unsigned char*>(temp_buffer.data()),
          32, // Float output
          (unsigned) 0);
      ErrorChecker::check_dedisp_error(error,"execute");

      // Get a pointer to the final trials data
      std::vector<float> const& data = trials.get_data();
      std::cout << "Trials total size: " << data.size() * sizeof(float) << " bytes" << std::endl;
      float* ptr = reinterpret_cast<float*>(trials.get_data_ptr());

      // Loop over the trials and for each take the data from the temporary buffer
      // and memcpy it into the correct location in the final trials object
      std::cout << "Performing transpose/merge of Dedisp output samples" << std::endl;

      for (std::size_t trial_idx = 0; trial_idx < dm_list.size(); ++trial_idx)
      {
        // Calculate destination offset for trails pointer
        //std::cout << "Trial IDx " << trial_idx << std::endl;
        std::size_t offset = total_out_nsamps * trial_idx + start_sample;
        //std::cout << "Offset " << offset << std::endl;
        //std::cout << "Temp offset " << dedisp_samples * trial_idx << std::endl;
        //std::cout << "Trials size " << trials.get_data().size() << std::endl;
        //std::cout << "Temp size " << temp_buffer.size() << std::endl;
        //std::cout << "nsamps to copy " << nsamps_to_copy << std::endl;

        //std::cout << "Dest offset: " << offset * sizeof(float)
        //          << " size: " << sizeof(float) * trials.get_count() * trials.get_nsamps()
        //          << " remaining: " << sizeof(float) * trials.get_count() * trials.get_nsamps() - offset * sizeof(float)
        //          << " to_copy: " << sizeof(float) * nsamps_to_copy << std::endl;

        std::memcpy( reinterpret_cast<char*>(ptr + offset),
                     reinterpret_cast<char*>(temp_buffer.data() + dedisp_samples * trial_idx),
                     sizeof(float) * nsamps_to_copy);
      }

      // Update the start_sample based on the number of samples output by dedisp
      start_sample += dedisp_samples;
      //std::cout << "Updating start sample to " << start_sample << std::endl;
    }

  }
};

<|endoftext|>


<commit_before>/***************************************************************************
* Copyright (c) 2016, Johan Mabille and Sylvain Corlay                     *
*                                                                          *
* Distributed under the terms of the BSD 3-Clause License.                 *
*                                                                          *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XTENSOR_CONFIG_HPP
#define XTENSOR_CONFIG_HPP

#define XTENSOR_VERSION_MAJOR 0
#define XTENSOR_VERSION_MINOR 8
#define XTENSOR_VERSION_PATCH 4

// DETECT 3.6 <= clang < 3.8 for compiler bug workaround.
#ifdef __clang__
    #if __clang_major__ == 3 && __clang_minor__ < 8
        #define X_OLD_CLANG
        #include <initializer_list>
        #include <vector>
    #endif
#endif

#ifndef DEFAULT_DATA_CONTAINER
#define DEFAULT_DATA_CONTAINER(T, A) uvector<T, A>
#endif

#ifndef DEFAULT_SHAPE_CONTAINER
#define DEFAULT_SHAPE_CONTAINER(T, EA, SA) \
    std::vector<typename DEFAULT_DATA_CONTAINER(T, EA)::size_type, SA>
#endif

#ifndef DEFAULT_LAYOUT
#define DEFAULT_LAYOUT layout_type::row_major
#endif

#endif
<commit_msg>Release 0.9.0<commit_after>/***************************************************************************
* Copyright (c) 2016, Johan Mabille and Sylvain Corlay                     *
*                                                                          *
* Distributed under the terms of the BSD 3-Clause License.                 *
*                                                                          *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XTENSOR_CONFIG_HPP
#define XTENSOR_CONFIG_HPP

#define XTENSOR_VERSION_MAJOR 0
#define XTENSOR_VERSION_MINOR 9
#define XTENSOR_VERSION_PATCH 0

// DETECT 3.6 <= clang < 3.8 for compiler bug workaround.
#ifdef __clang__
    #if __clang_major__ == 3 && __clang_minor__ < 8
        #define X_OLD_CLANG
        #include <initializer_list>
        #include <vector>
    #endif
#endif

#ifndef DEFAULT_DATA_CONTAINER
#define DEFAULT_DATA_CONTAINER(T, A) uvector<T, A>
#endif

#ifndef DEFAULT_SHAPE_CONTAINER
#define DEFAULT_SHAPE_CONTAINER(T, EA, SA) \
    std::vector<typename DEFAULT_DATA_CONTAINER(T, EA)::size_type, SA>
#endif

#ifndef DEFAULT_LAYOUT
#define DEFAULT_LAYOUT layout_type::row_major
#endif

#endif
<|endoftext|>