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

#include "test_precomp.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;
using namespace std;

class CV_GrfmtWriteBigImageTest : public cvtest::BaseTest
{
public:
    void run(int)
    {
        try
        {
            ts->printf(cvtest::TS::LOG, "start  reading big image\n");
            Mat img = imread(string(ts->get_data_path()) + "readwrite/read.png");
            ts->printf(cvtest::TS::LOG, "finish reading big image\n");
            if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
            ts->printf(cvtest::TS::LOG, "start  writing big image\n");
            imwrite(cv::tempfile(".png"), img);
            ts->printf(cvtest::TS::LOG, "finish writing big image\n");
        }
        catch(...)
        {
            ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
        }
        ts->set_failed_test_info(cvtest::TS::OK);
    }
};

string ext_from_int(int ext)
{
#ifdef HAVE_PNG
    if (ext == 0) return ".png";
#endif
    if (ext == 1) return ".bmp";
    if (ext == 2) return ".pgm";
#ifdef HAVE_TIFF
    if (ext == 3) return ".tiff";
#endif
    return "";
}

class CV_GrfmtWriteSequenceImageTest : public cvtest::BaseTest
{
public:
    void run(int)
    {
        try
        {
            const int img_r = 640;
            const int img_c = 480;

            for (int k = 1; k <= 5; ++k)
            {
                for (int ext = 0; ext < 4; ++ext) // 0 - png, 1 - bmp, 2 - pgm, 3 - tiff
                {
                    if(ext_from_int(ext).empty())
                        continue;
                    for (int num_channels = 1; num_channels <= 3; num_channels+=2)
                    {
                        ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_8U, num_channels, ext_from_int(ext).c_str());
                        Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
                        circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));

                        string img_path = cv::tempfile(ext_from_int(ext).c_str());
                        ts->printf(ts->LOG, "writing      image : %s\n", img_path.c_str());
                        imwrite(img_path, img);

                        ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str());
                        Mat img_test = imread(img_path, CV_LOAD_IMAGE_UNCHANGED);

                        if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);

                        CV_Assert(img.size() == img_test.size());
                        CV_Assert(img.type() == img_test.type());

                        double n = norm(img, img_test);
                        if ( n > 1.0)
                        {
                            ts->printf(ts->LOG, "norm = %f \n", n);
                            ts->set_failed_test_info(ts->FAIL_MISMATCH);
                        }
                    }
		    if (ext == 3 /*TIFF*/)
                    {
                    /* 4 channels should stay 4 channels */
                        int num_channels = 4;
                        ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_8U,num_channels, ext_from_int(ext).c_str());
                        Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
                        circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));

                        string img_path = cv::tempfile(ext_from_int(ext).c_str());
                        ts->printf(ts->LOG, "writing      image : %s\n", img_path.c_str());
                        imwrite(img_path, img);

                        ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str());
                        Mat img_test = imread(img_path, CV_LOAD_IMAGE_UNCHANGED);

                        if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);

                        CV_Assert(img.size() == img_test.size());
                        CV_Assert(img.type() == img_test.type());
                        CV_Assert(img.channels() == 4);

                        double n = norm(img, img_test);
                        if ( n > 1.0)
                        {
                            ts->printf(ts->LOG, "norm = %f \n", n);
                            ts->set_failed_test_info(ts->FAIL_MISMATCH);
                        }

                    }

                }

#ifdef HAVE_JPEG
                for (int num_channels = 1; num_channels <= 3; num_channels+=2)
                {
                    // jpeg
                    ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_8U, num_channels, ".jpg");
                    Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
                    circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));

                    string filename = cv::tempfile(".jpg");
                    imwrite(filename, img);
                    img = imread(filename, CV_LOAD_IMAGE_UNCHANGED);

                    filename = string(ts->get_data_path() + "readwrite/test_" + char(k + 48) + "_c" + char(num_channels + 48) + ".jpg");
                    ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str());
                    Mat img_test = imread(filename, CV_LOAD_IMAGE_UNCHANGED);

                    if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);

                    CV_Assert(img.size() == img_test.size());
                    CV_Assert(img.type() == img_test.type());

                    double n = norm(img, img_test);
                    if ( n > 1.0)
                    {
                        ts->printf(ts->LOG, "norm = %f \n", n);
                        ts->set_failed_test_info(ts->FAIL_MISMATCH);
                    }
                }
#endif

#ifdef HAVE_TIFF
                for (int num_channels = 1; num_channels <= 3; num_channels+=2)
                {
                    // tiff
                    ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_16U, num_channels, ".tiff");
                    Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_16U, num_channels), Scalar::all(0));
                    circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));

                    string filename = cv::tempfile(".tiff");
                    imwrite(filename, img);
                    ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str());
                    Mat img_test = imread(filename, CV_LOAD_IMAGE_UNCHANGED);

                    if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);

                    CV_Assert(img.size() == img_test.size());

                    ts->printf(ts->LOG, "img      : %d ; %d \n", img.channels(), img.depth());
                    ts->printf(ts->LOG, "img_test : %d ; %d \n", img_test.channels(), img_test.depth());

                    CV_Assert(img.type() == img_test.type());

                    double n = norm(img, img_test);
                    if ( n > 1.0)
                    {
                        ts->printf(ts->LOG, "norm = %f \n", n);
                        ts->set_failed_test_info(ts->FAIL_MISMATCH);
                    }
                }
#endif
            }
        }
        catch(const cv::Exception & e)
        {
            ts->printf(ts->LOG, "Exception: %s\n" , e.what());
            ts->set_failed_test_info(ts->FAIL_MISMATCH);
        }
    }
};

class CV_GrfmtReadBMPRLE8Test : public cvtest::BaseTest
{
public:
    void run(int)
    {
        try
        {
            Mat rle = imread(string(ts->get_data_path()) + "readwrite/rle8.bmp");
            Mat bmp = imread(string(ts->get_data_path()) + "readwrite/ordinary.bmp");
            if (norm(rle-bmp)>1.e-10)
                ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
        }
        catch(...)
        {
            ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
        }
        ts->set_failed_test_info(cvtest::TS::OK);
    }
};

#ifdef HAVE_PNG
TEST(Highgui_Image, write_big) { CV_GrfmtWriteBigImageTest test; test.safe_run(); }
#endif

TEST(Highgui_Image, write_imageseq) { CV_GrfmtWriteSequenceImageTest test; test.safe_run(); }

TEST(Highgui_Image, read_bmp_rle8) { CV_GrfmtReadBMPRLE8Test test; test.safe_run(); }

#ifdef HAVE_PNG
class CV_GrfmtPNGEncodeTest : public cvtest::BaseTest
{
public:
    void run(int)
    {
        try
        {
            vector<uchar> buff;
            Mat im = Mat::zeros(1000,1000, CV_8U);
            //randu(im, 0, 256);
            vector<int> param;
            param.push_back(CV_IMWRITE_PNG_COMPRESSION);
            param.push_back(3); //default(3) 0-9.
            cv::imencode(".png" ,im ,buff, param);

            // hangs
            Mat im2 = imdecode(buff,CV_LOAD_IMAGE_ANYDEPTH);
        }
        catch(...)
        {
            ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
        }
        ts->set_failed_test_info(cvtest::TS::OK);
    }
};

TEST(Highgui_Image, encode_png) { CV_GrfmtPNGEncodeTest test; test.safe_run(); }

TEST(Highgui_ImreadVSCvtColor, regression)
{
    cvtest::TS& ts = *cvtest::TS::ptr();

    const int MAX_MEAN_DIFF = 1;
    const int MAX_ABS_DIFF = 10;

    string imgName = string(ts.get_data_path()) + "/../cv/shared/lena.png";
    Mat original_image = imread(imgName);
    Mat gray_by_codec = imread(imgName, 0);
    Mat gray_by_cvt;

    cvtColor(original_image, gray_by_cvt, CV_BGR2GRAY);

    Mat diff;
    absdiff(gray_by_codec, gray_by_cvt, diff);

    double actual_avg_diff = (double)mean(diff)[0];
    double actual_maxval, actual_minval;
    minMaxLoc(diff, &actual_minval, &actual_maxval);
    //printf("actual avg = %g, actual maxdiff = %g, npixels = %d\n", actual_avg_diff, actual_maxval, (int)diff.total());

    EXPECT_LT(actual_avg_diff, MAX_MEAN_DIFF);
    EXPECT_LT(actual_maxval, MAX_ABS_DIFF);
}
#endif

#ifdef HAVE_JPEG
TEST(Highgui_Jpeg, encode_empty)
{
    cv::Mat img;
    std::vector<uchar> jpegImg;

    ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception);
}
#endif

#ifdef HAVE_TIFF

// these defines are used to resolve conflict between tiff.h and opencv2/core/types_c.h
#define uint64 uint64_hack_
#define int64 int64_hack_
#include "tiff.h"

TEST(Highgui_Tiff, decode_tile16384x16384)
{
    // see issue #2161
    cv::Mat big(16384, 16384, CV_8UC1, cv::Scalar::all(0));
    string file3 = cv::tempfile(".tiff");
    string file4 = cv::tempfile(".tiff");

    std::vector<int> params;
    params.push_back(TIFFTAG_ROWSPERSTRIP);
    params.push_back(big.rows);
    cv::imwrite(file4, big, params);
    cv::imwrite(file3, big.colRange(0, big.cols - 1), params);
    big.release();

    try
    {
        cv::imread(file3);
        EXPECT_NO_THROW(cv::imread(file4));
    }
    catch(const std::bad_alloc&)
    {
        // have no enough memory
    }

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

#include "test_precomp.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;
using namespace std;

class CV_GrfmtWriteBigImageTest : public cvtest::BaseTest
{
public:
    void run(int)
    {
        try
        {
            ts->printf(cvtest::TS::LOG, "start  reading big image\n");
            Mat img = imread(string(ts->get_data_path()) + "readwrite/read.png");
            ts->printf(cvtest::TS::LOG, "finish reading big image\n");
            if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
            ts->printf(cvtest::TS::LOG, "start  writing big image\n");
            imwrite(cv::tempfile(".png"), img);
            ts->printf(cvtest::TS::LOG, "finish writing big image\n");
        }
        catch(...)
        {
            ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
        }
        ts->set_failed_test_info(cvtest::TS::OK);
    }
};

string ext_from_int(int ext)
{
#ifdef HAVE_PNG
    if (ext == 0) return ".png";
#endif
    if (ext == 1) return ".bmp";
    if (ext == 2) return ".pgm";
#ifdef HAVE_TIFF
    if (ext == 3) return ".tiff";
#endif
    return "";
}

class CV_GrfmtWriteSequenceImageTest : public cvtest::BaseTest
{
public:
    void run(int)
    {
        try
        {
            const int img_r = 640;
            const int img_c = 480;

            for (int k = 1; k <= 5; ++k)
            {
                for (int ext = 0; ext < 4; ++ext) // 0 - png, 1 - bmp, 2 - pgm, 3 - tiff
                {
                    if(ext_from_int(ext).empty())
                        continue;
                    for (int num_channels = 1; num_channels <= 3; num_channels+=2)
                    {
                        ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_8U, num_channels, ext_from_int(ext).c_str());
                        Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
                        circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));

                        string img_path = cv::tempfile(ext_from_int(ext).c_str());
                        ts->printf(ts->LOG, "writing      image : %s\n", img_path.c_str());
                        imwrite(img_path, img);

                        ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str());
                        Mat img_test = imread(img_path, CV_LOAD_IMAGE_UNCHANGED);

                        if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);

                        CV_Assert(img.size() == img_test.size());
                        CV_Assert(img.type() == img_test.type());

                        double n = norm(img, img_test);
                        if ( n > 1.0)
                        {
                            ts->printf(ts->LOG, "norm = %f \n", n);
                            ts->set_failed_test_info(ts->FAIL_MISMATCH);
                        }
                    }
                    if (ext == 3 /*TIFF*/)
                    {
                    /* 4 channels should stay 4 channels */
                        int num_channels = 4;
                        ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_8U,num_channels, ext_from_int(ext).c_str());
                        Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
                        circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));

                        string img_path = cv::tempfile(ext_from_int(ext).c_str());
                        ts->printf(ts->LOG, "writing      image : %s\n", img_path.c_str());
                        imwrite(img_path, img);

                        ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str());
                        Mat img_test = imread(img_path, CV_LOAD_IMAGE_UNCHANGED);

                        if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);

                        CV_Assert(img.size() == img_test.size());
                        CV_Assert(img.type() == img_test.type());
                        CV_Assert(img_test.channels() == 4);

                        double n = norm(img, img_test);
                        if ( n > 1.0)
                        {
                            ts->printf(ts->LOG, "norm = %f \n", n);
                            ts->set_failed_test_info(ts->FAIL_MISMATCH);
                        }

                    }
                }

#ifdef HAVE_JPEG
                for (int num_channels = 1; num_channels <= 3; num_channels+=2)
                {
                    // jpeg
                    ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_8U, num_channels, ".jpg");
                    Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
                    circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));

                    string filename = cv::tempfile(".jpg");
                    imwrite(filename, img);
                    img = imread(filename, CV_LOAD_IMAGE_UNCHANGED);

                    filename = string(ts->get_data_path() + "readwrite/test_" + char(k + 48) + "_c" + char(num_channels + 48) + ".jpg");
                    ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str());
                    Mat img_test = imread(filename, CV_LOAD_IMAGE_UNCHANGED);

                    if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);

                    CV_Assert(img.size() == img_test.size());
                    CV_Assert(img.type() == img_test.type());

                    double n = norm(img, img_test);
                    if ( n > 1.0)
                    {
                        ts->printf(ts->LOG, "norm = %f \n", n);
                        ts->set_failed_test_info(ts->FAIL_MISMATCH);
                    }
                }
#endif

#ifdef HAVE_TIFF
                for (int num_channels = 1; num_channels <= 3; num_channels+=2)
                {
                    // tiff
                    ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_16U, num_channels, ".tiff");
                    Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_16U, num_channels), Scalar::all(0));
                    circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));

                    string filename = cv::tempfile(".tiff");
                    imwrite(filename, img);
                    ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str());
                    Mat img_test = imread(filename, CV_LOAD_IMAGE_UNCHANGED);

                    if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);

                    CV_Assert(img.size() == img_test.size());

                    ts->printf(ts->LOG, "img      : %d ; %d \n", img.channels(), img.depth());
                    ts->printf(ts->LOG, "img_test : %d ; %d \n", img_test.channels(), img_test.depth());

                    CV_Assert(img.type() == img_test.type());

                    double n = norm(img, img_test);
                    if ( n > 1.0)
                    {
                        ts->printf(ts->LOG, "norm = %f \n", n);
                        ts->set_failed_test_info(ts->FAIL_MISMATCH);
                    }
                }
#endif
            }
        }
        catch(const cv::Exception & e)
        {
            ts->printf(ts->LOG, "Exception: %s\n" , e.what());
            ts->set_failed_test_info(ts->FAIL_MISMATCH);
        }
    }
};

class CV_GrfmtReadBMPRLE8Test : public cvtest::BaseTest
{
public:
    void run(int)
    {
        try
        {
            Mat rle = imread(string(ts->get_data_path()) + "readwrite/rle8.bmp");
            Mat bmp = imread(string(ts->get_data_path()) + "readwrite/ordinary.bmp");
            if (norm(rle-bmp)>1.e-10)
                ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
        }
        catch(...)
        {
            ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
        }
        ts->set_failed_test_info(cvtest::TS::OK);
    }
};

#ifdef HAVE_PNG
TEST(Highgui_Image, write_big) { CV_GrfmtWriteBigImageTest test; test.safe_run(); }
#endif

TEST(Highgui_Image, write_imageseq) { CV_GrfmtWriteSequenceImageTest test; test.safe_run(); }

TEST(Highgui_Image, read_bmp_rle8) { CV_GrfmtReadBMPRLE8Test test; test.safe_run(); }

#ifdef HAVE_PNG
class CV_GrfmtPNGEncodeTest : public cvtest::BaseTest
{
public:
    void run(int)
    {
        try
        {
            vector<uchar> buff;
            Mat im = Mat::zeros(1000,1000, CV_8U);
            //randu(im, 0, 256);
            vector<int> param;
            param.push_back(CV_IMWRITE_PNG_COMPRESSION);
            param.push_back(3); //default(3) 0-9.
            cv::imencode(".png" ,im ,buff, param);

            // hangs
            Mat im2 = imdecode(buff,CV_LOAD_IMAGE_ANYDEPTH);
        }
        catch(...)
        {
            ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
        }
        ts->set_failed_test_info(cvtest::TS::OK);
    }
};

TEST(Highgui_Image, encode_png) { CV_GrfmtPNGEncodeTest test; test.safe_run(); }

TEST(Highgui_ImreadVSCvtColor, regression)
{
    cvtest::TS& ts = *cvtest::TS::ptr();

    const int MAX_MEAN_DIFF = 1;
    const int MAX_ABS_DIFF = 10;

    string imgName = string(ts.get_data_path()) + "/../cv/shared/lena.png";
    Mat original_image = imread(imgName);
    Mat gray_by_codec = imread(imgName, 0);
    Mat gray_by_cvt;

    cvtColor(original_image, gray_by_cvt, CV_BGR2GRAY);

    Mat diff;
    absdiff(gray_by_codec, gray_by_cvt, diff);

    double actual_avg_diff = (double)mean(diff)[0];
    double actual_maxval, actual_minval;
    minMaxLoc(diff, &actual_minval, &actual_maxval);
    //printf("actual avg = %g, actual maxdiff = %g, npixels = %d\n", actual_avg_diff, actual_maxval, (int)diff.total());

    EXPECT_LT(actual_avg_diff, MAX_MEAN_DIFF);
    EXPECT_LT(actual_maxval, MAX_ABS_DIFF);
}
#endif

#ifdef HAVE_JPEG
TEST(Highgui_Jpeg, encode_empty)
{
    cv::Mat img;
    std::vector<uchar> jpegImg;

    ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception);
}
#endif

#ifdef HAVE_TIFF

// these defines are used to resolve conflict between tiff.h and opencv2/core/types_c.h
#define uint64 uint64_hack_
#define int64 int64_hack_
#include "tiff.h"

TEST(Highgui_Tiff, decode_tile16384x16384)
{
    // see issue #2161
    cv::Mat big(16384, 16384, CV_8UC1, cv::Scalar::all(0));
    string file3 = cv::tempfile(".tiff");
    string file4 = cv::tempfile(".tiff");

    std::vector<int> params;
    params.push_back(TIFFTAG_ROWSPERSTRIP);
    params.push_back(big.rows);
    cv::imwrite(file4, big, params);
    cv::imwrite(file3, big.colRange(0, big.cols - 1), params);
    big.release();

    try
    {
        cv::imread(file3);
        EXPECT_NO_THROW(cv::imread(file4));
    }
    catch(const std::bad_alloc&)
    {
        // have no enough memory
    }

    remove(file3.c_str());
    remove(file4.c_str());
}
#endif
<|endoftext|>


<commit_before>// Copyright 2016 Google Inc.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. 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.
// 3. The name of the author may not be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR 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.

#include <google_smart_card_pcsc_lite_server/global.h>

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

#include <string>
#include <thread>
#include <utility>

extern "C" {
#include "winscard.h"
#include "debuglog.h"
#include "hotplug.h"
#include "readerfactory.h"
#include "sys_generic.h"
#include "winscard_svc.h"
}

#include <google_smart_card_common/ipc_emulation.h>
#include <google_smart_card_common/logging/logging.h>
#include <google_smart_card_common/messaging/typed_message.h>
#include <google_smart_card_common/value.h>
#include <google_smart_card_common/value_conversion.h>

#include "server_sockets_manager.h"

// Old versions of Emscripten have buggy multi-threading - so bail out if the
// developer still hasn't updated their local Emscripten version.
#ifdef __EMSCRIPTEN__
#if __EMSCRIPTEN_major__ < 2 ||                                \
    (__EMSCRIPTEN_major__ == 2 && __EMSCRIPTEN_minor__ == 0 && \
     __EMSCRIPTEN_tiny__ < 31)
#error "Emscripten >=2.0.31 must be used"
#endif
#endif  // __EMSCRIPTEN__

namespace google_smart_card {

namespace {

PcscLiteServerGlobal* g_pcsc_lite_server = nullptr;

constexpr char kLoggingPrefix[] = "[PC/SC-Lite NaCl port] ";

// Constants for message types that are sent to the JavaScript side. These
// strings must match the ones in reader-tracker.js.
constexpr char kReaderInitAddMessageType[] = "reader_init_add";
constexpr char kReaderFinishAddMessageType[] = "reader_finish_add";
constexpr char kReaderRemoveMessageType[] = "reader_remove";

// Message data for the message that notifies the JavaScript side that a reader
// is being added by the PC/SC-Lite daemon.
struct ReaderInitAddMessageData {
  std::string reader_name;
  int port;
  std::string device;
};

// Message data for the message that notifies the JavaScript side that a reader
// is completely added by the PC/SC-Lite daemon.
struct ReaderFinishAddMessageData {
  std::string reader_name;
  int port;
  std::string device;
  long return_code;
};

// Message data for the message that notifies the JavaScript side that a reader
// is removed by the PC/SC-Lite daemon.
struct ReaderRemoveMessageData {
  std::string reader_name;
  int port;
};

void PcscLiteServerDaemonThreadMain() {
  // TODO(emaxx): Stop the event loop during pp::Instance destruction.
  while (true) {
    GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "[daemon thread] "
                                << "Waiting for the new connected clients...";
    uint32_t server_socket_file_descriptor = static_cast<uint32_t>(
        PcscLiteServerSocketsManager::GetInstance()->WaitAndPop());

    GOOGLE_SMART_CARD_LOG_DEBUG
        << kLoggingPrefix << "[daemon thread] A new "
        << "client was connected, starting a handler thread...";
    // Note: even though the CreateContextThread function accepts its
    // server_socket_file_descriptor argument by pointer, it doesn't store the
    // pointer itself anywhere - so it's safe to use a local variable here.
    // FIXME(emaxx): Deal with cases when CreateContextThread returns errors.
    // Looks like it may happen legitimately when the abusive client(s) request
    // to establish too many requests. Probably, some limitation should be
    // applied to all clients.
    GOOGLE_SMART_CARD_CHECK(
        ::CreateContextThread(&server_socket_file_descriptor) ==
        SCARD_S_SUCCESS);
  }
}

}  // namespace

template <>
StructValueDescriptor<ReaderInitAddMessageData>::Description
StructValueDescriptor<ReaderInitAddMessageData>::GetDescription() {
  // Note: Strings passed to WithField() below must match the property names in
  // reader-tracker.js.
  return Describe("ReaderInitAddMessageData")
      .WithField(&ReaderInitAddMessageData::reader_name, "readerName")
      .WithField(&ReaderInitAddMessageData::port, "port")
      .WithField(&ReaderInitAddMessageData::device, "device");
}

template <>
StructValueDescriptor<ReaderFinishAddMessageData>::Description
StructValueDescriptor<ReaderFinishAddMessageData>::GetDescription() {
  // Note: Strings passed to WithField() below must match the property names in
  // reader-tracker.js.
  return Describe("ReaderFinishAddMessageData")
      .WithField(&ReaderFinishAddMessageData::reader_name, "readerName")
      .WithField(&ReaderFinishAddMessageData::port, "port")
      .WithField(&ReaderFinishAddMessageData::device, "device")
      .WithField(&ReaderFinishAddMessageData::return_code, "returnCode");
}

template <>
StructValueDescriptor<ReaderRemoveMessageData>::Description
StructValueDescriptor<ReaderRemoveMessageData>::GetDescription() {
  // Note: Strings passed to WithField() below must match the property names in
  // reader-tracker.js.
  return Describe("ReaderRemoveMessageData")
      .WithField(&ReaderRemoveMessageData::reader_name, "readerName")
      .WithField(&ReaderRemoveMessageData::port, "port");
}

PcscLiteServerGlobal::PcscLiteServerGlobal(GlobalContext* global_context)
    : global_context_(global_context) {
  GOOGLE_SMART_CARD_CHECK(!g_pcsc_lite_server);
  g_pcsc_lite_server = this;
}

PcscLiteServerGlobal::~PcscLiteServerGlobal() {
  GOOGLE_SMART_CARD_CHECK(g_pcsc_lite_server == this);
  g_pcsc_lite_server = nullptr;
}

// static
const PcscLiteServerGlobal* PcscLiteServerGlobal::GetInstance() {
  GOOGLE_SMART_CARD_CHECK(g_pcsc_lite_server);
  return g_pcsc_lite_server;
}

void PcscLiteServerGlobal::InitializeAndRunDaemonThread() {
  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Initialization...";

  IpcEmulation::CreateGlobalInstance();
  PcscLiteServerSocketsManager::CreateGlobalInstance();

  ::SYS_InitRandom();

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Setting up PC/SC-Lite "
                              << "logging...";
  ::DebugLogSetLogType(DEBUGLOG_SYSLOG_DEBUG);
#ifdef NDEBUG
  ::DebugLogSetLevel(PCSC_LOG_ERROR);
#else
  ::DebugLogSetLevel(PCSC_LOG_DEBUG);
  ::DebugLogSetCategory(DEBUG_CATEGORY_APDU | DEBUG_CATEGORY_SW);
#endif
  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "PC/SC-Lite logging was "
                              << "set up.";

  LONG return_code;

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Allocating reader "
                              << "structures...";
  return_code = ::RFAllocateReaderSpace(0);
  GOOGLE_SMART_CARD_LOG_DEBUG
      << kLoggingPrefix << "Reader structures "
      << "allocation finished with the following result: \""
      << ::pcsc_stringify_error(return_code) << "\".";
  GOOGLE_SMART_CARD_CHECK(return_code == SCARD_S_SUCCESS);

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Performing initial hot "
                              << "plug drivers search...";
  return_code = ::HPSearchHotPluggables();
  GOOGLE_SMART_CARD_LOG_DEBUG
      << kLoggingPrefix << "Initial hot plug "
      << "drivers search finished with the following result code: "
      << return_code << ".";
  GOOGLE_SMART_CARD_CHECK(return_code == 0);

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Registering for hot "
                              << "plug events...";
  // FIXME(emaxx): Currently this ends up on polling the libusb each second, as
  // it doesn't provide any way to subscribe for the device list change. But
  // it's possible to optimize this onto publisher-pattern-style implementation,
  // by handling the chrome.usb API events (see
  // <https://developer.chrome.com/apps/usb#Events>) and using them in a
  // replacement implementation of the currently used original hotplug_libusb.c
  // source file.
  return_code = ::HPRegisterForHotplugEvents();
  GOOGLE_SMART_CARD_LOG_DEBUG
      << kLoggingPrefix << "Registering for hot "
      << "plug events finished with the following result code: " << return_code
      << ".";
  GOOGLE_SMART_CARD_CHECK(return_code == 0);

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Allocating client "
                              << "structures...";
  return_code = ::ContextsInitialize(0, 0);
  GOOGLE_SMART_CARD_LOG_DEBUG
      << kLoggingPrefix << "Client structures "
      << "allocation finished with the following result code: " << return_code
      << "...";
  GOOGLE_SMART_CARD_CHECK(return_code == 1);

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Waiting for the readers "
                              << "initialization...";
  ::RFWaitForReaderInit();
  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Waiting for the readers "
                              << "initialization finished.";

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Starting PC/SC-Lite "
                              << "daemon thread...";
  std::thread daemon_thread(PcscLiteServerDaemonThreadMain);
  daemon_thread.detach();
  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "PC/SC-Lite daemon "
                              << "thread has started.";

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Initialization "
                              << "successfully finished.";
}

void PcscLiteServerGlobal::PostReaderInitAddMessage(const char* reader_name,
                                                    int port,
                                                    const char* device) const {
  ReaderInitAddMessageData message_data;
  message_data.reader_name = reader_name;
  message_data.port = port;
  message_data.device = device;
  PostMessage(kReaderInitAddMessageType,
              ConvertToValueOrDie(std::move(message_data)));
}

void PcscLiteServerGlobal::PostReaderFinishAddMessage(const char* reader_name,
                                                      int port,
                                                      const char* device,
                                                      long return_code) const {
  ReaderFinishAddMessageData message_data;
  message_data.reader_name = reader_name;
  message_data.port = port;
  message_data.device = device;
  message_data.return_code = return_code;
  PostMessage(kReaderFinishAddMessageType,
              ConvertToValueOrDie(std::move(message_data)));
}

void PcscLiteServerGlobal::PostReaderRemoveMessage(const char* reader_name,
                                                   int port) const {
  ReaderRemoveMessageData message_data;
  message_data.reader_name = reader_name;
  message_data.port = port;
  PostMessage(kReaderRemoveMessageType,
              ConvertToValueOrDie(std::move(message_data)));
}

void PcscLiteServerGlobal::PostMessage(const char* type,
                                       Value message_data) const {
  TypedMessage typed_message;
  typed_message.type = type;
  typed_message.data = std::move(message_data);
  global_context_->PostMessageToJs(
      ConvertToValueOrDie(std::move(typed_message)));
}

}  // namespace google_smart_card
<commit_msg>Fix preprocessor issue with PC/SC and std headers (#557)<commit_after>// Copyright 2016 Google Inc.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. 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.
// 3. The name of the author may not be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR 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.

#include <google_smart_card_pcsc_lite_server/global.h>

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

#include <string>
#include <thread>
#include <utility>

#include <google_smart_card_common/ipc_emulation.h>
#include <google_smart_card_common/logging/logging.h>
#include <google_smart_card_common/messaging/typed_message.h>
#include <google_smart_card_common/value.h>
#include <google_smart_card_common/value_conversion.h>

#include "server_sockets_manager.h"

// Include the C headers after all other includes, because the preprocessor
// definitions from them interfere with the symbols from the standard C++
// library.
extern "C" {
#include "winscard.h"
#include "debuglog.h"
#include "hotplug.h"
#include "readerfactory.h"
#include "sys_generic.h"
#include "winscard_svc.h"
}

// Old versions of Emscripten have buggy multi-threading - so bail out if the
// developer still hasn't updated their local Emscripten version.
#ifdef __EMSCRIPTEN__
#if __EMSCRIPTEN_major__ < 2 ||                                \
    (__EMSCRIPTEN_major__ == 2 && __EMSCRIPTEN_minor__ == 0 && \
     __EMSCRIPTEN_tiny__ < 31)
#error "Emscripten >=2.0.31 must be used"
#endif
#endif  // __EMSCRIPTEN__

namespace google_smart_card {

namespace {

PcscLiteServerGlobal* g_pcsc_lite_server = nullptr;

constexpr char kLoggingPrefix[] = "[PC/SC-Lite NaCl port] ";

// Constants for message types that are sent to the JavaScript side. These
// strings must match the ones in reader-tracker.js.
constexpr char kReaderInitAddMessageType[] = "reader_init_add";
constexpr char kReaderFinishAddMessageType[] = "reader_finish_add";
constexpr char kReaderRemoveMessageType[] = "reader_remove";

// Message data for the message that notifies the JavaScript side that a reader
// is being added by the PC/SC-Lite daemon.
struct ReaderInitAddMessageData {
  std::string reader_name;
  int port;
  std::string device;
};

// Message data for the message that notifies the JavaScript side that a reader
// is completely added by the PC/SC-Lite daemon.
struct ReaderFinishAddMessageData {
  std::string reader_name;
  int port;
  std::string device;
  long return_code;
};

// Message data for the message that notifies the JavaScript side that a reader
// is removed by the PC/SC-Lite daemon.
struct ReaderRemoveMessageData {
  std::string reader_name;
  int port;
};

void PcscLiteServerDaemonThreadMain() {
  // TODO(emaxx): Stop the event loop during pp::Instance destruction.
  while (true) {
    GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "[daemon thread] "
                                << "Waiting for the new connected clients...";
    uint32_t server_socket_file_descriptor = static_cast<uint32_t>(
        PcscLiteServerSocketsManager::GetInstance()->WaitAndPop());

    GOOGLE_SMART_CARD_LOG_DEBUG
        << kLoggingPrefix << "[daemon thread] A new "
        << "client was connected, starting a handler thread...";
    // Note: even though the CreateContextThread function accepts its
    // server_socket_file_descriptor argument by pointer, it doesn't store the
    // pointer itself anywhere - so it's safe to use a local variable here.
    // FIXME(emaxx): Deal with cases when CreateContextThread returns errors.
    // Looks like it may happen legitimately when the abusive client(s) request
    // to establish too many requests. Probably, some limitation should be
    // applied to all clients.
    GOOGLE_SMART_CARD_CHECK(
        ::CreateContextThread(&server_socket_file_descriptor) ==
        SCARD_S_SUCCESS);
  }
}

}  // namespace

template <>
StructValueDescriptor<ReaderInitAddMessageData>::Description
StructValueDescriptor<ReaderInitAddMessageData>::GetDescription() {
  // Note: Strings passed to WithField() below must match the property names in
  // reader-tracker.js.
  return Describe("ReaderInitAddMessageData")
      .WithField(&ReaderInitAddMessageData::reader_name, "readerName")
      .WithField(&ReaderInitAddMessageData::port, "port")
      .WithField(&ReaderInitAddMessageData::device, "device");
}

template <>
StructValueDescriptor<ReaderFinishAddMessageData>::Description
StructValueDescriptor<ReaderFinishAddMessageData>::GetDescription() {
  // Note: Strings passed to WithField() below must match the property names in
  // reader-tracker.js.
  return Describe("ReaderFinishAddMessageData")
      .WithField(&ReaderFinishAddMessageData::reader_name, "readerName")
      .WithField(&ReaderFinishAddMessageData::port, "port")
      .WithField(&ReaderFinishAddMessageData::device, "device")
      .WithField(&ReaderFinishAddMessageData::return_code, "returnCode");
}

template <>
StructValueDescriptor<ReaderRemoveMessageData>::Description
StructValueDescriptor<ReaderRemoveMessageData>::GetDescription() {
  // Note: Strings passed to WithField() below must match the property names in
  // reader-tracker.js.
  return Describe("ReaderRemoveMessageData")
      .WithField(&ReaderRemoveMessageData::reader_name, "readerName")
      .WithField(&ReaderRemoveMessageData::port, "port");
}

PcscLiteServerGlobal::PcscLiteServerGlobal(GlobalContext* global_context)
    : global_context_(global_context) {
  GOOGLE_SMART_CARD_CHECK(!g_pcsc_lite_server);
  g_pcsc_lite_server = this;
}

PcscLiteServerGlobal::~PcscLiteServerGlobal() {
  GOOGLE_SMART_CARD_CHECK(g_pcsc_lite_server == this);
  g_pcsc_lite_server = nullptr;
}

// static
const PcscLiteServerGlobal* PcscLiteServerGlobal::GetInstance() {
  GOOGLE_SMART_CARD_CHECK(g_pcsc_lite_server);
  return g_pcsc_lite_server;
}

void PcscLiteServerGlobal::InitializeAndRunDaemonThread() {
  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Initialization...";

  IpcEmulation::CreateGlobalInstance();
  PcscLiteServerSocketsManager::CreateGlobalInstance();

  ::SYS_InitRandom();

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Setting up PC/SC-Lite "
                              << "logging...";
  ::DebugLogSetLogType(DEBUGLOG_SYSLOG_DEBUG);
#ifdef NDEBUG
  ::DebugLogSetLevel(PCSC_LOG_ERROR);
#else
  ::DebugLogSetLevel(PCSC_LOG_DEBUG);
  ::DebugLogSetCategory(DEBUG_CATEGORY_APDU | DEBUG_CATEGORY_SW);
#endif
  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "PC/SC-Lite logging was "
                              << "set up.";

  LONG return_code;

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Allocating reader "
                              << "structures...";
  return_code = ::RFAllocateReaderSpace(0);
  GOOGLE_SMART_CARD_LOG_DEBUG
      << kLoggingPrefix << "Reader structures "
      << "allocation finished with the following result: \""
      << ::pcsc_stringify_error(return_code) << "\".";
  GOOGLE_SMART_CARD_CHECK(return_code == SCARD_S_SUCCESS);

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Performing initial hot "
                              << "plug drivers search...";
  return_code = ::HPSearchHotPluggables();
  GOOGLE_SMART_CARD_LOG_DEBUG
      << kLoggingPrefix << "Initial hot plug "
      << "drivers search finished with the following result code: "
      << return_code << ".";
  GOOGLE_SMART_CARD_CHECK(return_code == 0);

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Registering for hot "
                              << "plug events...";
  // FIXME(emaxx): Currently this ends up on polling the libusb each second, as
  // it doesn't provide any way to subscribe for the device list change. But
  // it's possible to optimize this onto publisher-pattern-style implementation,
  // by handling the chrome.usb API events (see
  // <https://developer.chrome.com/apps/usb#Events>) and using them in a
  // replacement implementation of the currently used original hotplug_libusb.c
  // source file.
  return_code = ::HPRegisterForHotplugEvents();
  GOOGLE_SMART_CARD_LOG_DEBUG
      << kLoggingPrefix << "Registering for hot "
      << "plug events finished with the following result code: " << return_code
      << ".";
  GOOGLE_SMART_CARD_CHECK(return_code == 0);

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Allocating client "
                              << "structures...";
  return_code = ::ContextsInitialize(0, 0);
  GOOGLE_SMART_CARD_LOG_DEBUG
      << kLoggingPrefix << "Client structures "
      << "allocation finished with the following result code: " << return_code
      << "...";
  GOOGLE_SMART_CARD_CHECK(return_code == 1);

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Waiting for the readers "
                              << "initialization...";
  ::RFWaitForReaderInit();
  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Waiting for the readers "
                              << "initialization finished.";

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Starting PC/SC-Lite "
                              << "daemon thread...";
  std::thread daemon_thread(PcscLiteServerDaemonThreadMain);
  daemon_thread.detach();
  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "PC/SC-Lite daemon "
                              << "thread has started.";

  GOOGLE_SMART_CARD_LOG_DEBUG << kLoggingPrefix << "Initialization "
                              << "successfully finished.";
}

void PcscLiteServerGlobal::PostReaderInitAddMessage(const char* reader_name,
                                                    int port,
                                                    const char* device) const {
  ReaderInitAddMessageData message_data;
  message_data.reader_name = reader_name;
  message_data.port = port;
  message_data.device = device;
  PostMessage(kReaderInitAddMessageType,
              ConvertToValueOrDie(std::move(message_data)));
}

void PcscLiteServerGlobal::PostReaderFinishAddMessage(const char* reader_name,
                                                      int port,
                                                      const char* device,
                                                      long return_code) const {
  ReaderFinishAddMessageData message_data;
  message_data.reader_name = reader_name;
  message_data.port = port;
  message_data.device = device;
  message_data.return_code = return_code;
  PostMessage(kReaderFinishAddMessageType,
              ConvertToValueOrDie(std::move(message_data)));
}

void PcscLiteServerGlobal::PostReaderRemoveMessage(const char* reader_name,
                                                   int port) const {
  ReaderRemoveMessageData message_data;
  message_data.reader_name = reader_name;
  message_data.port = port;
  PostMessage(kReaderRemoveMessageType,
              ConvertToValueOrDie(std::move(message_data)));
}

void PcscLiteServerGlobal::PostMessage(const char* type,
                                       Value message_data) const {
  TypedMessage typed_message;
  typed_message.type = type;
  typed_message.data = std::move(message_data);
  global_context_->PostMessageToJs(
      ConvertToValueOrDie(std::move(typed_message)));
}

}  // namespace google_smart_card
<|endoftext|>


<commit_before>#include "MLP.h"

MLP::MLP()
{
    //ctor
}
MLP::MLP(int h1pNo, int h2pNo, double qtty, int maxIter, bool validationMethod)
{
    //no of neurons in hidden layer
    h1No = h1pNo;
    h2No = h2pNo;
 //   param = qtty;
   // this->dL = dL; //learning
   // this->dT = dT; //testing
 //   this->decay = wDecay;
    this->maxIter = maxIter;
    this->kFoldValidation = validationMethod;

    alglib::mlpcreatetrainercls(X.getObjectAt(0).getFeatureCount(), X.getClassCount(), trn); //qtt of input features, number of classes to be produced

    double wstep = 0.000;
    mlpsetdecay(trn, 0.001); // by default we set moderate weight decay
    mlpsetcond(trn, wstep, this->maxIter);     // * we choose iterations limit as stopping condition (another condition - step size - is zero, which means than this condition is not active)

    alglib::mlpcreatec2(X.getObjectAt(0).getFeatureCount(), h1No, h2No, X.getClassCount(), network); //create nn network with noofinput features, 2 hidden layers, noofclasses (and sore to network variable)

    if (this->kFoldValidation == true) //do kfold validation
    {
        ClusterizationMethods::initializeData();

        alglib::mlpsetdataset(trn, ClusterizationMethods::learnSet, ClusterizationMethods::learnObjQtty); //attach learning data to data set

        alglib::mlpkfoldcv(trn, network, 1, int(qtty), rep);
    }
    else
    {
        ClusterizationMethods::initializeData(qtty, 100 - qtty);

        alglib::mlpsetdataset(trn, ClusterizationMethods::learnSet, ClusterizationMethods::learnObjQtty); //attach learning data to data set

        alglib::mlptrainnetwork(trn, network, 1, rep); // train network NRestarts=1, network is trained from random initial state. With NRestarts=0, network is trained without randomization (original state is used as initial point).
        alglib::integer_1d_array Subset;
        Subset.setlength(10);
        alglib::mlpallerrorssubset(network, testSet, testObjQtty, Subset, -1, repp);
    }
    //ctor
    // now get network error // do not calculate cross-validation since it validates the topology of the network
}

MLP::~MLP()
{
    //dtor
}

ObjectMatrix MLP::getProjection()
{
    //int cols = X.getClassCount();
    int ftCount = X.getObjectAt(0).getFeatureCount();
    int objCount = X.getObjectCount();

    initializeYMatrix(objCount, ftCount + X.getClassCount());

    alglib::real_1d_array tmpYObj;
    alglib::real_1d_array tmpXObj;

    tmpYObj.setlength(ftCount);
    tmpXObj.setlength(X.getClassCount());

    DataObject tmpO;
    for (int i = 0; i < objCount; i++)
    {
        tmpO = X.getObjectAt(i);
        for (int ft = 0; ft < ftCount; ft++)
        {
            double feature = tmpO.getFeatureAt(ft);
            tmpYObj(ft) = feature;
            Y.updateDataObject(i, ft, feature);
        }

        alglib::mlpprocess(network, tmpYObj, tmpXObj);

        double max_prob = tmpXObj(0);
        int indx = 0;

        for (int j = 0; j < X.getClassCount(); j++)
        {
            Y.updateDataObject(i, j + ftCount, tmpXObj(j));
            if (max_prob < tmpXObj(j))
            {
                max_prob = tmpXObj(j);
                indx = j;
            }
        }

        if (tmpO.getClassLabel() != -1)
            Y.updateDataObjectClass(i, tmpO.getClassLabel());
        else
            Y.updateDataObjectClass(i, indx);
    }

        std::vector <std::string > probabilities; probabilities.reserve(0);

        for (int i = 0; i < X.getClassCount(); i++)
            probabilities.push_back("probability_" + X.getStringClassAttributes().at(i));

        Y.addAtributes(probabilities);

        Y.setPrintClass(X.getStringClassAttributes());

    return Y;
}

double MLP::getStress()
{
    if (this->kFoldValidation)
    {
        return rep.avgrelerror;
    }
    else
    {
        return repp.avgrelerror;
    }
//}
    /*
    * Rep.RelCLSError - fraction of misclassified cases.
    * Rep.AvgCE - acerage cross-entropy
    * Rep.RMSError - root-mean-square error
    * Rep.AvgError - average error
    * Rep.AvgRelError - average relative error
    */
  return rep.rmserror;
}
<commit_msg>Updated MLP network construction regarding passed parameters<commit_after>#include "MLP.h"

MLP::MLP()
{
    //ctor
}
MLP::MLP(int h1pNo, int h2pNo, double qtty, int maxIter, bool validationMethod)
{
    //no of neurons in hidden layer
    h1No = h1pNo;
    h2No = h2pNo;
 //   param = qtty;
   // this->dL = dL; //learning
   // this->dT = dT; //testing
 //   this->decay = wDecay;
    this->maxIter = maxIter;
    this->kFoldValidation = validationMethod;

    alglib::mlpcreatetrainercls(X.getObjectAt(0).getFeatureCount(), X.getClassCount(), trn); //qtt of input features, number of classes to be produced

    double wstep = 0.000;
    mlpsetdecay(trn, 0.001); // by default we set moderate weight decay
    mlpsetcond(trn, wstep, this->maxIter);     // * we choose iterations limit as stopping condition (another condition - step size - is zero, which means than this condition is not active)

    if ((h1No > 0) && (h2No > 0))
        alglib::mlpcreatec2(X.getObjectAt(0).getFeatureCount(), h1No, h2No, X.getClassCount(), network); //create nn network with noofinput features, 2 hidden layers, noofclasses (and sore to network variable)
    if ((h1No > 0) && (h2No == 0))
         alglib::mlpcreatec1(X.getObjectAt(0).getFeatureCount(), h1No, X.getClassCount(), network); //create nn network with no of input features, 1 hidden layer, noofclasses (and sore to network variable)
    if ((h1No == 0) && (h2No == 0))
        alglib::mlpcreatec0(X.getObjectAt(0).getFeatureCount(), X.getClassCount(), network); //create nn network with no of input features, 0 hidden layer, noofclasses (and sore to network variable)
///h2No must be non zero

    if (this->kFoldValidation == true) //do kfold validation
    {
        ClusterizationMethods::initializeData();

        alglib::mlpsetdataset(trn, ClusterizationMethods::learnSet, ClusterizationMethods::learnObjQtty); //attach learning data to data set

        alglib::mlpkfoldcv(trn, network, 1, int(qtty), rep);
    }
    else
    {
        ClusterizationMethods::initializeData(qtty, 100 - qtty);

        alglib::mlpsetdataset(trn, ClusterizationMethods::learnSet, ClusterizationMethods::learnObjQtty); //attach learning data to data set

        alglib::mlptrainnetwork(trn, network, 1, rep); // train network NRestarts=1, network is trained from random initial state. With NRestarts=0, network is trained without randomization (original state is used as initial point).
        alglib::integer_1d_array Subset;
        Subset.setlength(10);
        alglib::mlpallerrorssubset(network, testSet, testObjQtty, Subset, -1, repp);
    }
    //ctor
    // now get network error // do not calculate cross-validation since it validates the topology of the network
}

MLP::~MLP()
{
    //dtor
}

ObjectMatrix MLP::getProjection()
{
    //int cols = X.getClassCount();
    int ftCount = X.getObjectAt(0).getFeatureCount();
    int objCount = X.getObjectCount();

    initializeYMatrix(objCount, ftCount + X.getClassCount());

    alglib::real_1d_array tmpYObj;
    alglib::real_1d_array tmpXObj;

    tmpYObj.setlength(ftCount);
    tmpXObj.setlength(X.getClassCount());

    DataObject tmpO;
    for (int i = 0; i < objCount; i++)
    {
        tmpO = X.getObjectAt(i);
        for (int ft = 0; ft < ftCount; ft++)
        {
            double feature = tmpO.getFeatureAt(ft);
            tmpYObj(ft) = feature;
            Y.updateDataObject(i, ft, feature);
        }

        alglib::mlpprocess(network, tmpYObj, tmpXObj);

        double max_prob = tmpXObj(0);
        int indx = 0;

        for (int j = 0; j < X.getClassCount(); j++)
        {
            Y.updateDataObject(i, j + ftCount, tmpXObj(j));
            if (max_prob < tmpXObj(j))
            {
                max_prob = tmpXObj(j);
                indx = j;
            }
        }

        if (tmpO.getClassLabel() != -1)
            Y.updateDataObjectClass(i, tmpO.getClassLabel());
        else
            Y.updateDataObjectClass(i, indx);
    }

        std::vector <std::string > probabilities; probabilities.reserve(0);

        for (int i = 0; i < X.getClassCount(); i++)
            probabilities.push_back("probClass" + X.getStringClassAttributes().at(i));

        Y.addAtributes(probabilities);

        Y.setPrintClass(X.getStringClassAttributes());

    return Y;
}

double MLP::getStress()
{
    if (this->kFoldValidation)
    {
        return rep.avgrelerror;
    }
    else
    {
        return repp.avgrelerror;
    }
//}
    /*
    * Rep.RelCLSError - fraction of misclassified cases.
    * Rep.AvgCE - acerage cross-entropy
    * Rep.RMSError - root-mean-square error
    * Rep.AvgError - average error
    * Rep.AvgRelError - average relative error
    */
  return rep.rmserror;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Script Generator project on Qt Labs.
**
** $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 "shellheadergenerator.h"
#include "fileout.h"

#include <QtCore/QDir>

#include <qdebug.h>

QString ShellHeaderGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const
{
  return QString("PythonQtWrapper_%1.h").arg(meta_class->name());
}

void ShellHeaderGenerator::writeFieldAccessors(QTextStream &s, const AbstractMetaField *field)
{
  const AbstractMetaFunction *setter = field->setter();
  const AbstractMetaFunction *getter = field->getter();

  // static fields are not supported (yet?)
  if (setter->isStatic()) return;

  // Uuid data4 did not work (TODO: move to typesystem...(
  if (field->enclosingClass()->name()=="QUuid" &&  setter->name()=="data4") return;
  if (field->enclosingClass()->name()=="QIPv6Address") return;

  if (!field->type()->isConstant()) {
    writeFunctionSignature(s, setter, 0, QString(),
                           Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | ShowStatic | UnderscoreSpaces));
    s << "{ theWrappedObject->" << field->name() << " = " << setter->arguments()[0]->argumentName() << "; }\n";
  }

  writeFunctionSignature(s, getter, 0, QString(),
                         Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
  s << "{ return theWrappedObject->" << field->name() << "; }\n";
}

void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
{
  QString builtIn = ShellGenerator::isBuiltIn(meta_class->name())?"_builtin":"";
  QString pro_file_name = meta_class->package().replace(".", "_") + builtIn + "/" + meta_class->package().replace(".", "_") + builtIn + ".pri";
  priGenerator->addHeader(pro_file_name, fileNameForClass(meta_class));
  setupGenerator->addClass(meta_class->package().replace(".", "_") + builtIn, meta_class);

  QString include_block = "PYTHONQTWRAPPER_" + meta_class->name().toUpper() + "_H";

  s << "#ifndef " << include_block << endl
    << "#define " << include_block << endl << endl;

  Include inc = meta_class->typeEntry()->include();
  ShellGenerator::writeInclude(s, inc);

  s << "#include <QObject>" << endl << endl;
  s << "#include <PythonQt.h>" << endl << endl;

  IncludeList list = meta_class->typeEntry()->extraIncludes();
  qSort(list.begin(), list.end());
  foreach (const Include &inc, list) {
    ShellGenerator::writeInclude(s, inc);
  }
  s << endl;

  AbstractMetaFunctionList ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
    | AbstractMetaClass::WasVisible
    | AbstractMetaClass::NotRemovedFromTargetLang);

  if (meta_class->qualifiedCppName().contains("Ssl")) {
    s << "#ifndef QT_NO_OPENSSL"  << endl;
  }

  // Shell-------------------------------------------------------------------
  if (meta_class->generateShellClass()) {

    AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class);

    s << "class " << shellClassName(meta_class)
      << " : public " << meta_class->qualifiedCppName() << endl << "{" << endl;
    s << "public:" << endl;
    foreach(AbstractMetaFunction* fun, ctors) {
      s << "    ";
      writeFunctionSignature(s, fun, 0,"PythonQtShell_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ":" << meta_class->qualifiedCppName() << "(";
      QString scriptFunctionName = fun->originalName();
      AbstractMetaArgumentList args = fun->arguments();
      for (int i = 0; i < args.size(); ++i) {
        if (i > 0)
          s << ", ";
        s << args.at(i)->argumentName();
      }
      s << "),_wrapper(NULL) {};" << endl;
    }
    s << endl;
    s << "   ~" << shellClassName(meta_class) << "();" << endl;

    foreach(AbstractMetaFunction* fun, virtualsForShell) {
      s << "virtual ";
      writeFunctionSignature(s, fun, 0, QString(),
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ";" << endl;
    }
    s << endl;
    s << "  PythonQtInstanceWrapper* _wrapper; " << endl;

    s << "};" << endl << endl;
  }

  // Promoter-------------------------------------------------------------------
  AbstractMetaFunctionList promoteFunctions = getProtectedFunctionsThatNeedPromotion(meta_class);
  if (!promoteFunctions.isEmpty()) {
    s << "class " << promoterClassName(meta_class)
      << " : public " << meta_class->qualifiedCppName() << endl << "{ public:" << endl;

    foreach(AbstractMetaFunction* fun, promoteFunctions) {
      s << "inline ";
      writeFunctionSignature(s, fun, 0, "promoted_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << " { ";
      QString scriptFunctionName = fun->originalName();
      AbstractMetaArgumentList args = fun->arguments();
      if (fun->type())
        s << "return ";
      s << meta_class->qualifiedCppName() << "::";
      s << fun->originalName() << "(";
      for (int i = 0; i < args.size(); ++i) {
        if (i > 0)
          s << ", ";
        s << args.at(i)->argumentName();
      }
      s << "); }" << endl;
    }

    s << "};" << endl << endl;
  }

  // Wrapper-------------------------------------------------------------------

  s << "class " << wrapperClassName(meta_class)
    << " : public QObject" << endl
    << "{ Q_OBJECT" << endl;

  s << "public:" << endl;

  AbstractMetaEnumList enums1 = meta_class->enums();
  AbstractMetaEnumList enums;
  QList<FlagsTypeEntry*> flags;
  foreach(AbstractMetaEnum* enum1, enums1) {
    // catch gadgets and enums that are not exported on QObjects...
    if (enum1->wasPublic() && (!meta_class->isQObject() || !enum1->hasQEnumsDeclaration())) {
      enums << enum1;
      if (enum1->typeEntry()->flags()) {
        flags << enum1->typeEntry()->flags();
      }
    }
  }
  if (enums.count()) {
    s << "Q_ENUMS(";
    foreach(AbstractMetaEnum* enum1, enums) {
      s << enum1->name() << " ";
    }
    s << ")" << endl;

    if (flags.count()) {
      s << "Q_FLAGS(";
      foreach(FlagsTypeEntry* flag1, flags) {
        QString origName = flag1->originalName();
        int idx = origName.lastIndexOf("::");
        if (idx!= -1) {
          origName = origName.mid(idx+2);
        }
        s << origName << " ";
      }
      s << ")" << endl;
    }

    foreach(AbstractMetaEnum* enum1, enums) {
      s << "enum " << enum1->name() << "{" << endl;
      bool first = true;
      foreach(AbstractMetaEnumValue* value, enum1->values()) {
        if (first) { first = false; }
        else { s << ", "; }
        s << "  " << value->name() << " = " << meta_class->qualifiedCppName() << "::" << value->name();
      }
      s << "};" << endl;
    }
    if (flags.count()) {
      foreach(AbstractMetaEnum* enum1, enums) {
        if (enum1->typeEntry()->flags()) {
          QString origName = enum1->typeEntry()->flags()->originalName();
          int idx = origName.lastIndexOf("::");
          if (idx!= -1) {
            origName = origName.mid(idx+2);
          }
          s << "Q_DECLARE_FLAGS("<< origName << ", " << enum1->name() <<")"<<endl;
        }
      }
    }
  }
  s << "public slots:" << endl;
  if (meta_class->generateShellClass() || !meta_class->isAbstract()) {

    bool copyConstructorSeen = false;
    bool defaultConstructorSeen = false;
    foreach (const AbstractMetaFunction *fun, ctors) {
      if (!fun->isPublic() || fun->isAbstract()) { continue; }
      s << meta_class->qualifiedCppName() << "* ";
      writeFunctionSignature(s, fun, 0, "new_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic));
      s << ";" << endl;
      if (fun->arguments().size()==1 && meta_class->qualifiedCppName() == fun->arguments().at(0)->type()->typeEntry()->qualifiedCppName()) {
        copyConstructorSeen = true;
      }
      if (fun->arguments().size()==0) {
        defaultConstructorSeen = true;
      }
    }

    if (meta_class->typeEntry()->isValue()
        && !copyConstructorSeen && defaultConstructorSeen) {
      QString className = meta_class->generateShellClass()?shellClassName(meta_class):meta_class->qualifiedCppName();
      s << meta_class->qualifiedCppName() << "* new_" << meta_class->name() << "(const " << meta_class->qualifiedCppName() << "& other) {" << endl;
      s << className << "* a = new " << className << "();" << endl;
      s << "*((" << meta_class->qualifiedCppName() << "*)a) = other;" << endl;
      s << "return a; }" << endl;
    }
  }
  if (meta_class->hasPublicDestructor() && !meta_class->isNamespace()) {
    s << "void delete_" << meta_class->name() << "(" << meta_class->qualifiedCppName() << "* obj) { delete obj; } ";
    s << endl;
  }

  AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);

  foreach (const AbstractMetaFunction *function, functions) {
    if (!function->isSlot() || function->isVirtual()) {
      s << "   ";
      writeFunctionSignature(s, function, 0, QString(),
        Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ";" << endl;
    }
  }
  if (meta_class->hasDefaultToStringFunction() || meta_class->hasToStringCapability()) {
    s << "    QString py_toString(" << meta_class->qualifiedCppName() << "*);" << endl;
  }
  if (meta_class->hasDefaultIsNull()) {
    s << "    bool __nonzero__(" << meta_class->qualifiedCppName() << "* obj) { return !obj->isNull(); }" << endl;
  }

  // Field accessors
  foreach (const AbstractMetaField *field, meta_class->fields()) {
    if (field->isPublic()) {
      writeFieldAccessors(s, field);
    }
  }

  writeInjectedCode(s, meta_class);

  s  << "};" << endl << endl;
  if (meta_class->qualifiedCppName().contains("Ssl")) {
    s << "#endif"  << endl << endl;
  }

  s  << "#endif // " << include_block << endl;

}

void ShellHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class)
{
  CodeSnipList code_snips = meta_class->typeEntry()->codeSnips();
  foreach (const CodeSnip &cs, code_snips) {
    if (cs.language == TypeSystem::PyWrapperDeclaration) {
      s << cs.code() << endl;
    }
  }
}
<commit_msg>readded linefeed<commit_after>/****************************************************************************
**
** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Script Generator project on Qt Labs.
**
** $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 "shellheadergenerator.h"
#include "fileout.h"

#include <QtCore/QDir>

#include <qdebug.h>

QString ShellHeaderGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const
{
  return QString("PythonQtWrapper_%1.h").arg(meta_class->name());
}

void ShellHeaderGenerator::writeFieldAccessors(QTextStream &s, const AbstractMetaField *field)
{
  const AbstractMetaFunction *setter = field->setter();
  const AbstractMetaFunction *getter = field->getter();

  // static fields are not supported (yet?)
  if (setter->isStatic()) return;

  // Uuid data4 did not work (TODO: move to typesystem...(
  if (field->enclosingClass()->name()=="QUuid" &&  setter->name()=="data4") return;
  if (field->enclosingClass()->name()=="QIPv6Address") return;

  if (!field->type()->isConstant()) {
    writeFunctionSignature(s, setter, 0, QString(),
                           Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | ShowStatic | UnderscoreSpaces));
    s << "{ theWrappedObject->" << field->name() << " = " << setter->arguments()[0]->argumentName() << "; }\n";
  }

  writeFunctionSignature(s, getter, 0, QString(),
                         Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
  s << "{ return theWrappedObject->" << field->name() << "; }\n";
}

void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
{
  QString builtIn = ShellGenerator::isBuiltIn(meta_class->name())?"_builtin":"";
  QString pro_file_name = meta_class->package().replace(".", "_") + builtIn + "/" + meta_class->package().replace(".", "_") + builtIn + ".pri";
  priGenerator->addHeader(pro_file_name, fileNameForClass(meta_class));
  setupGenerator->addClass(meta_class->package().replace(".", "_") + builtIn, meta_class);

  QString include_block = "PYTHONQTWRAPPER_" + meta_class->name().toUpper() + "_H";

  s << "#ifndef " << include_block << endl
    << "#define " << include_block << endl << endl;

  Include inc = meta_class->typeEntry()->include();
  ShellGenerator::writeInclude(s, inc);

  s << "#include <QObject>" << endl << endl;
  s << "#include <PythonQt.h>" << endl << endl;

  IncludeList list = meta_class->typeEntry()->extraIncludes();
  qSort(list.begin(), list.end());
  foreach (const Include &inc, list) {
    ShellGenerator::writeInclude(s, inc);
  }
  s << endl;

  AbstractMetaFunctionList ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
    | AbstractMetaClass::WasVisible
    | AbstractMetaClass::NotRemovedFromTargetLang);

  if (meta_class->qualifiedCppName().contains("Ssl")) {
    s << "#ifndef QT_NO_OPENSSL"  << endl;
  }

  // Shell-------------------------------------------------------------------
  if (meta_class->generateShellClass()) {

    AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class);

    s << "class " << shellClassName(meta_class)
      << " : public " << meta_class->qualifiedCppName() << endl << "{" << endl;
    s << "public:" << endl;
    foreach(AbstractMetaFunction* fun, ctors) {
      s << "    ";
      writeFunctionSignature(s, fun, 0,"PythonQtShell_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ":" << meta_class->qualifiedCppName() << "(";
      QString scriptFunctionName = fun->originalName();
      AbstractMetaArgumentList args = fun->arguments();
      for (int i = 0; i < args.size(); ++i) {
        if (i > 0)
          s << ", ";
        s << args.at(i)->argumentName();
      }
      s << "),_wrapper(NULL) {};" << endl;
    }
    s << endl;
    s << "   ~" << shellClassName(meta_class) << "();" << endl;
    s << endl;

    foreach(AbstractMetaFunction* fun, virtualsForShell) {
      s << "virtual ";
      writeFunctionSignature(s, fun, 0, QString(),
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ";" << endl;
    }
    s << endl;
    s << "  PythonQtInstanceWrapper* _wrapper; " << endl;

    s << "};" << endl << endl;
  }

  // Promoter-------------------------------------------------------------------
  AbstractMetaFunctionList promoteFunctions = getProtectedFunctionsThatNeedPromotion(meta_class);
  if (!promoteFunctions.isEmpty()) {
    s << "class " << promoterClassName(meta_class)
      << " : public " << meta_class->qualifiedCppName() << endl << "{ public:" << endl;

    foreach(AbstractMetaFunction* fun, promoteFunctions) {
      s << "inline ";
      writeFunctionSignature(s, fun, 0, "promoted_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << " { ";
      QString scriptFunctionName = fun->originalName();
      AbstractMetaArgumentList args = fun->arguments();
      if (fun->type())
        s << "return ";
      s << meta_class->qualifiedCppName() << "::";
      s << fun->originalName() << "(";
      for (int i = 0; i < args.size(); ++i) {
        if (i > 0)
          s << ", ";
        s << args.at(i)->argumentName();
      }
      s << "); }" << endl;
    }

    s << "};" << endl << endl;
  }

  // Wrapper-------------------------------------------------------------------

  s << "class " << wrapperClassName(meta_class)
    << " : public QObject" << endl
    << "{ Q_OBJECT" << endl;

  s << "public:" << endl;

  AbstractMetaEnumList enums1 = meta_class->enums();
  AbstractMetaEnumList enums;
  QList<FlagsTypeEntry*> flags;
  foreach(AbstractMetaEnum* enum1, enums1) {
    // catch gadgets and enums that are not exported on QObjects...
    if (enum1->wasPublic() && (!meta_class->isQObject() || !enum1->hasQEnumsDeclaration())) {
      enums << enum1;
      if (enum1->typeEntry()->flags()) {
        flags << enum1->typeEntry()->flags();
      }
    }
  }
  if (enums.count()) {
    s << "Q_ENUMS(";
    foreach(AbstractMetaEnum* enum1, enums) {
      s << enum1->name() << " ";
    }
    s << ")" << endl;

    if (flags.count()) {
      s << "Q_FLAGS(";
      foreach(FlagsTypeEntry* flag1, flags) {
        QString origName = flag1->originalName();
        int idx = origName.lastIndexOf("::");
        if (idx!= -1) {
          origName = origName.mid(idx+2);
        }
        s << origName << " ";
      }
      s << ")" << endl;
    }

    foreach(AbstractMetaEnum* enum1, enums) {
      s << "enum " << enum1->name() << "{" << endl;
      bool first = true;
      foreach(AbstractMetaEnumValue* value, enum1->values()) {
        if (first) { first = false; }
        else { s << ", "; }
        s << "  " << value->name() << " = " << meta_class->qualifiedCppName() << "::" << value->name();
      }
      s << "};" << endl;
    }
    if (flags.count()) {
      foreach(AbstractMetaEnum* enum1, enums) {
        if (enum1->typeEntry()->flags()) {
          QString origName = enum1->typeEntry()->flags()->originalName();
          int idx = origName.lastIndexOf("::");
          if (idx!= -1) {
            origName = origName.mid(idx+2);
          }
          s << "Q_DECLARE_FLAGS("<< origName << ", " << enum1->name() <<")"<<endl;
        }
      }
    }
  }
  s << "public slots:" << endl;
  if (meta_class->generateShellClass() || !meta_class->isAbstract()) {

    bool copyConstructorSeen = false;
    bool defaultConstructorSeen = false;
    foreach (const AbstractMetaFunction *fun, ctors) {
      if (!fun->isPublic() || fun->isAbstract()) { continue; }
      s << meta_class->qualifiedCppName() << "* ";
      writeFunctionSignature(s, fun, 0, "new_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic));
      s << ";" << endl;
      if (fun->arguments().size()==1 && meta_class->qualifiedCppName() == fun->arguments().at(0)->type()->typeEntry()->qualifiedCppName()) {
        copyConstructorSeen = true;
      }
      if (fun->arguments().size()==0) {
        defaultConstructorSeen = true;
      }
    }

    if (meta_class->typeEntry()->isValue()
        && !copyConstructorSeen && defaultConstructorSeen) {
      QString className = meta_class->generateShellClass()?shellClassName(meta_class):meta_class->qualifiedCppName();
      s << meta_class->qualifiedCppName() << "* new_" << meta_class->name() << "(const " << meta_class->qualifiedCppName() << "& other) {" << endl;
      s << className << "* a = new " << className << "();" << endl;
      s << "*((" << meta_class->qualifiedCppName() << "*)a) = other;" << endl;
      s << "return a; }" << endl;
    }
  }
  if (meta_class->hasPublicDestructor() && !meta_class->isNamespace()) {
    s << "void delete_" << meta_class->name() << "(" << meta_class->qualifiedCppName() << "* obj) { delete obj; } ";
    s << endl;
  }

  AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);

  foreach (const AbstractMetaFunction *function, functions) {
    if (!function->isSlot() || function->isVirtual()) {
      s << "   ";
      writeFunctionSignature(s, function, 0, QString(),
        Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ";" << endl;
    }
  }
  if (meta_class->hasDefaultToStringFunction() || meta_class->hasToStringCapability()) {
    s << "    QString py_toString(" << meta_class->qualifiedCppName() << "*);" << endl;
  }
  if (meta_class->hasDefaultIsNull()) {
    s << "    bool __nonzero__(" << meta_class->qualifiedCppName() << "* obj) { return !obj->isNull(); }" << endl;
  }

  // Field accessors
  foreach (const AbstractMetaField *field, meta_class->fields()) {
    if (field->isPublic()) {
      writeFieldAccessors(s, field);
    }
  }

  writeInjectedCode(s, meta_class);

  s  << "};" << endl << endl;
  if (meta_class->qualifiedCppName().contains("Ssl")) {
    s << "#endif"  << endl << endl;
  }

  s  << "#endif // " << include_block << endl;

}

void ShellHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class)
{
  CodeSnipList code_snips = meta_class->typeEntry()->codeSnips();
  foreach (const CodeSnip &cs, code_snips) {
    if (cs.language == TypeSystem::PyWrapperDeclaration) {
      s << cs.code() << endl;
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef PRINT_HH_
#define PRINT_HH_

#include <boost/format.hpp>
#include <iostream>

inline void
apply_format(boost::format& fmt) {
}

template <typename A0, typename... Arest>
inline void
apply_format(boost::format& fmt, A0&& a0, Arest&&... arest) {
    apply_format(fmt % std::forward<A0>(a0), std::forward<Arest>(arest)...);
}

template <typename... A>
std::ostream&
fprint(std::ostream& os, boost::format& fmt, A&&... a) {
    apply_format(fmt, std::forward<A>(a)...);
    return os << fmt;
}

template <typename... A>
void
print(boost::format& fmt, A&&... a) {
    fprint(std::cout, fmt, std::forward<A>(a)...);
}

template <typename... A>
std::ostream&
fprint(std::ostream& os, const char* fmt, A&&... a) {
    boost::format bfmt(fmt);
    return fprint(os, bfmt, std::forward<A>(a)...);
}

template <typename... A>
void
print(const char* fmt, A&&... a) {
    boost::format bfmt(fmt);
    return print(bfmt, std::forward<A>(a)...);
}

template <typename... A>
std::string
sprint(const char* fmt, A&&... a) {
    boost::format bfmt(fmt);
    apply_format(bfmt, std::forward<A>(a)...);
    return bfmt.str();
}

template <typename Iterator>
std::string
format_separated(Iterator b, Iterator e, const char* sep = ", ") {
    std::string ret;
    if (b == e) {
        return ret;
    }
    ret += *b++;
    while (b != e) {
        ret += sep;
        ret += *b++;
    }
    return ret;
}

#endif /* PRINT_HH_ */
<commit_msg>print: add log() function<commit_after>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef PRINT_HH_
#define PRINT_HH_

#include <boost/format.hpp>
#include <iostream>
#include <iomanip>
#include <chrono>

inline void
apply_format(boost::format& fmt) {
}

template <typename A0, typename... Arest>
inline void
apply_format(boost::format& fmt, A0&& a0, Arest&&... arest) {
    apply_format(fmt % std::forward<A0>(a0), std::forward<Arest>(arest)...);
}

template <typename... A>
std::ostream&
fprint(std::ostream& os, boost::format& fmt, A&&... a) {
    apply_format(fmt, std::forward<A>(a)...);
    return os << fmt;
}

template <typename... A>
void
print(boost::format& fmt, A&&... a) {
    fprint(std::cout, fmt, std::forward<A>(a)...);
}

template <typename... A>
std::ostream&
fprint(std::ostream& os, const char* fmt, A&&... a) {
    boost::format bfmt(fmt);
    return fprint(os, bfmt, std::forward<A>(a)...);
}

template <typename... A>
void
print(const char* fmt, A&&... a) {
    boost::format bfmt(fmt);
    return print(bfmt, std::forward<A>(a)...);
}

template <typename... A>
std::string
sprint(const char* fmt, A&&... a) {
    boost::format bfmt(fmt);
    apply_format(bfmt, std::forward<A>(a)...);
    return bfmt.str();
}

template <typename Iterator>
std::string
format_separated(Iterator b, Iterator e, const char* sep = ", ") {
    std::string ret;
    if (b == e) {
        return ret;
    }
    ret += *b++;
    while (b != e) {
        ret += sep;
        ret += *b++;
    }
    return ret;
}

template <typename TimePoint>
struct usecfmt_wrapper {
    TimePoint val;
};

template <typename TimePoint>
inline
usecfmt_wrapper<TimePoint>
usecfmt(TimePoint tp) {
    return { tp };
};

template <typename Clock, typename Rep, typename Period>
std::ostream&
operator<<(std::ostream& os, usecfmt_wrapper<std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>> tp) {
    auto usec = std::chrono::duration_cast<std::chrono::microseconds>(tp.val.time_since_epoch()).count();
    std::ostream tmp(os.rdbuf());
    tmp << std::setw(12) << (usec / 1000000) << "." << std::setw(6) << std::setfill('0') << (usec % 1000000);
    return os;
}

template <typename... A>
void
log(A&&... a) {
    std::cout << usecfmt(std::chrono::high_resolution_clock::now()) << " ";
    print(std::forward<A>(a)...);
}

#endif /* PRINT_HH_ */
<|endoftext|>


<commit_before>#include "source-manager.hpp"

#include <pdal/Options.hpp>
#include <pdal/Reader.hpp>
#include <pdal/StageFactory.hpp>

#include <entwine/types/bbox.hpp>
#include <entwine/types/schema.hpp>
#include <entwine/types/simple-point-table.hpp>
#include <entwine/util/executor.hpp>

SourceManager::SourceManager(
        pdal::StageFactory& stageFactory,
        std::mutex& factoryMutex,
        std::string path,
        std::string driver)
    : m_stageFactory(stageFactory)
    , m_factoryMutex(factoryMutex)
    , m_options(new pdal::Options())
    , m_driver(driver)
    , m_schema(new entwine::Schema())
    , m_bbox(new entwine::BBox())
    , m_numPoints(0)
{
    m_options->add(pdal::Option("filename", path));

    // Use BBox::set() to avoid malformed BBox warning.
    m_bbox->set(
            entwine::Point(
                std::numeric_limits<double>::max(),
                std::numeric_limits<double>::max(),
                std::numeric_limits<double>::max()),
            entwine::Point(
                std::numeric_limits<double>::lowest(),
                std::numeric_limits<double>::lowest(),
                std::numeric_limits<double>::lowest()),
            true);

    // Determine the number of points and the bounds for this resource.
    {
        entwine::DimList dims;
        const auto type(pdal::Dimension::Type::Double);

        dims.push_back(entwine::DimInfo("X", pdal::Dimension::Id::X, type));
        dims.push_back(entwine::DimInfo("Y", pdal::Dimension::Id::Y, type));
        dims.push_back(entwine::DimInfo("Z", pdal::Dimension::Id::Z, type));

        entwine::Schema xyzSchema(dims);
        entwine::Executor executor(xyzSchema, true);

        auto bounder([this](pdal::PointView& view)
        {
            entwine::Point p;
            m_numPoints += view.size();

            for (std::size_t i = 0; i < view.size(); ++i)
            {
                p.x = view.getFieldAs<double>(pdal::Dimension::Id::X, i);
                p.y = view.getFieldAs<double>(pdal::Dimension::Id::Y, i);
                p.z = view.getFieldAs<double>(pdal::Dimension::Id::Z, i);

                m_bbox->grow(p);
            }
        });

        auto preview(executor.preview(path, nullptr, true));
        if (preview)
        {
            m_srs = preview->srs;
        }

        if (!executor.run(path, nullptr, bounder))
        {
            throw std::runtime_error("Could not execute resource: " + path);
        }
    }

    // Determine the native schema of the resource.
    {
        auto reader(createReader());
        entwine::SimplePointTable pointTable(*m_schema);
        reader->prepare(pointTable);
        m_schema->finalize();
    }
}

std::unique_ptr<pdal::Reader> SourceManager::createReader()
{
    std::unique_lock<std::mutex> lock(m_factoryMutex);
    std::unique_ptr<pdal::Reader> reader(
            static_cast<pdal::Reader*>(
                m_stageFactory.createStage(m_driver)));
    lock.unlock();

    reader->setOptions(*m_options);
    return reader;
}

<commit_msg>Update to different entwine API.<commit_after>#include "source-manager.hpp"

#include <pdal/Options.hpp>
#include <pdal/Reader.hpp>
#include <pdal/StageFactory.hpp>

#include <entwine/types/bbox.hpp>
#include <entwine/types/schema.hpp>
#include <entwine/types/simple-point-table.hpp>
#include <entwine/util/executor.hpp>

SourceManager::SourceManager(
        pdal::StageFactory& stageFactory,
        std::mutex& factoryMutex,
        std::string path,
        std::string driver)
    : m_stageFactory(stageFactory)
    , m_factoryMutex(factoryMutex)
    , m_options(new pdal::Options())
    , m_driver(driver)
    , m_schema(new entwine::Schema())
    , m_bbox(new entwine::BBox())
    , m_numPoints(0)
{
    m_options->add(pdal::Option("filename", path));

    // Use BBox::set() to avoid malformed BBox warning.
    m_bbox->set(
            entwine::Point(
                std::numeric_limits<double>::max(),
                std::numeric_limits<double>::max(),
                std::numeric_limits<double>::max()),
            entwine::Point(
                std::numeric_limits<double>::lowest(),
                std::numeric_limits<double>::lowest(),
                std::numeric_limits<double>::lowest()),
            true);

    // Determine the native schema of the resource.
    {
        auto reader(createReader());
        entwine::DataPool dataPool(0);
        entwine::SimplePointTable pointTable(dataPool, *m_schema);
        reader->prepare(pointTable);
        m_schema->finalize();
    }

    // Determine the number of points and the bounds for this resource.
    {
        entwine::DimList dims;
        const auto type(pdal::Dimension::Type::Double);

        dims.push_back(entwine::DimInfo("X", pdal::Dimension::Id::X, type));
        dims.push_back(entwine::DimInfo("Y", pdal::Dimension::Id::Y, type));
        dims.push_back(entwine::DimInfo("Z", pdal::Dimension::Id::Z, type));

        entwine::Schema xyzSchema(dims);
        entwine::Executor executor(true);

        entwine::DataPool dataPool(m_schema->pointSize());
        entwine::SimplePointTable table(dataPool, *m_schema);

        auto bounder([this, &table, &dataPool](pdal::PointView& view)
        {
            entwine::PooledDataStack stack;
            entwine::Point p;
            m_numPoints += view.size();

            for (std::size_t i = 0; i < view.size(); ++i)
            {
                p.x = view.getFieldAs<double>(pdal::Dimension::Id::X, i);
                p.y = view.getFieldAs<double>(pdal::Dimension::Id::Y, i);
                p.z = view.getFieldAs<double>(pdal::Dimension::Id::Z, i);

                m_bbox->grow(p);

                stack.push(table.getNode(i));
            }

            dataPool.release(stack);
        });

        auto preview(executor.preview(path, nullptr, true));
        if (preview)
        {
            m_srs = preview->srs;
        }

        if (!executor.run(table, path, nullptr, bounder))
        {
            throw std::runtime_error("Could not execute resource: " + path);
        }
    }
}

std::unique_ptr<pdal::Reader> SourceManager::createReader()
{
    std::unique_lock<std::mutex> lock(m_factoryMutex);
    std::unique_ptr<pdal::Reader> reader(
            static_cast<pdal::Reader*>(
                m_stageFactory.createStage(m_driver)));
    lock.unlock();

    reader->setOptions(*m_options);
    return reader;
}

<|endoftext|>