Home | History | Annotate | Download | only in test
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                           License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
     14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
     15 // Third party copyrights are property of their respective owners.
     16 //
     17 // Redistribution and use in source and binary forms, with or without modification,
     18 // are permitted provided that the following conditions are met:
     19 //
     20 //   * Redistribution's of source code must retain the above copyright notice,
     21 //     this list of conditions and the following disclaimer.
     22 //
     23 //   * Redistribution's in binary form must reproduce the above copyright notice,
     24 //     this list of conditions and the following disclaimer in the documentation
     25 //     and/or other materials provided with the distribution.
     26 //
     27 //   * The name of the copyright holders may not be used to endorse or promote products
     28 //     derived from this software without specific prior written permission.
     29 //
     30 // This software is provided by the copyright holders and contributors "as is" and
     31 // any express or implied warranties, including, but not limited to, the implied
     32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     33 // In no event shall the Intel Corporation or contributors be liable for any direct,
     34 // indirect, incidental, special, exemplary, or consequential damages
     35 // (including, but not limited to, procurement of substitute goods or services;
     36 // loss of use, data, or profits; or business interruption) however caused
     37 // and on any theory of liability, whether in contract, strict liability,
     38 // or tort (including negligence or otherwise) arising in any way out of
     39 // the use of this software, even if advised of the possibility of such damage.
     40 //
     41 //M*/
     42 
     43 #include "test_precomp.hpp"
     44 
     45 #include <fstream>
     46 
     47 using namespace cv;
     48 using namespace std;
     49 
     50 static
     51 bool mats_equal(const Mat& lhs, const Mat& rhs)
     52 {
     53     if (lhs.channels() != rhs.channels() ||
     54         lhs.depth() != rhs.depth() ||
     55         lhs.size().height != rhs.size().height ||
     56         lhs.size().width != rhs.size().width)
     57     {
     58         return false;
     59     }
     60 
     61     Mat diff = (lhs != rhs);
     62     const Scalar s = sum(diff);
     63     for (int i = 0; i < s.channels; ++i)
     64     {
     65         if (s[i] != 0)
     66         {
     67             return false;
     68         }
     69     }
     70 
     71     return true;
     72 }
     73 
     74 static
     75 bool imread_compare(const string& filepath, int flags = IMREAD_COLOR)
     76 {
     77     vector<Mat> pages;
     78     if (!imreadmulti(filepath, pages, flags) ||
     79         pages.empty())
     80     {
     81         return false;
     82     }
     83 
     84     const Mat single = imread(filepath, flags);
     85     return mats_equal(single, pages[0]);
     86 }
     87 
     88 TEST(Imgcodecs_imread, regression)
     89 {
     90     const char* const filenames[] =
     91     {
     92 #ifdef HAVE_JASPER
     93         "Rome.jp2",
     94 #endif
     95         "color_palette_alpha.png",
     96         "multipage.tif",
     97         "rle.hdr",
     98         "ordinary.bmp",
     99         "rle8.bmp",
    100         "test_1_c1.jpg"
    101     };
    102 
    103     const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/";
    104 
    105     for (size_t i = 0; i < sizeof(filenames) / sizeof(filenames[0]); ++i)
    106     {
    107         const string path = folder + string(filenames[i]);
    108         ASSERT_TRUE(imread_compare(path, IMREAD_UNCHANGED));
    109         ASSERT_TRUE(imread_compare(path, IMREAD_GRAYSCALE));
    110         ASSERT_TRUE(imread_compare(path, IMREAD_COLOR));
    111         ASSERT_TRUE(imread_compare(path, IMREAD_ANYDEPTH));
    112         ASSERT_TRUE(imread_compare(path, IMREAD_ANYCOLOR));
    113         if (path.substr(path.length() - 3) != "hdr")
    114         {
    115             // GDAL does not support hdr
    116             ASSERT_TRUE(imread_compare(path, IMREAD_LOAD_GDAL));
    117         }
    118     }
    119 }
    120 
    121 #ifdef HAVE_JASPER
    122 TEST(Imgcodecs_jasper, regression)
    123 {
    124     const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/";
    125 
    126     ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_COLOR));
    127     ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_GRAYSCALE));
    128     ASSERT_TRUE(imread_compare(folder + "Grey.jp2", IMREAD_COLOR));
    129     ASSERT_TRUE(imread_compare(folder + "Grey.jp2", IMREAD_GRAYSCALE));
    130 }
    131 #endif
    132 
    133 class CV_GrfmtWriteBigImageTest : public cvtest::BaseTest
    134 {
    135 public:
    136     void run(int)
    137     {
    138         try
    139         {
    140             ts->printf(cvtest::TS::LOG, "start  reading big image\n");
    141             Mat img = imread(string(ts->get_data_path()) + "readwrite/read.png");
    142             ts->printf(cvtest::TS::LOG, "finish reading big image\n");
    143             if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
    144             ts->printf(cvtest::TS::LOG, "start  writing big image\n");
    145             imwrite(cv::tempfile(".png"), img);
    146             ts->printf(cvtest::TS::LOG, "finish writing big image\n");
    147         }
    148         catch(...)
    149         {
    150             ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
    151         }
    152         ts->set_failed_test_info(cvtest::TS::OK);
    153     }
    154 };
    155 
    156 string ext_from_int(int ext)
    157 {
    158 #ifdef HAVE_PNG
    159     if (ext == 0) return ".png";
    160 #endif
    161     if (ext == 1) return ".bmp";
    162     if (ext == 2) return ".pgm";
    163 #ifdef HAVE_TIFF
    164     if (ext == 3) return ".tiff";
    165 #endif
    166     return "";
    167 }
    168 
    169 class CV_GrfmtWriteSequenceImageTest : public cvtest::BaseTest
    170 {
    171 public:
    172     void run(int)
    173     {
    174         try
    175         {
    176             const int img_r = 640;
    177             const int img_c = 480;
    178 
    179             for (int k = 1; k <= 5; ++k)
    180             {
    181                 for (int ext = 0; ext < 4; ++ext) // 0 - png, 1 - bmp, 2 - pgm, 3 - tiff
    182                 {
    183                     if(ext_from_int(ext).empty())
    184                         continue;
    185                     for (int num_channels = 1; num_channels <= 4; num_channels++)
    186                     {
    187                         if (num_channels == 2) continue;
    188                         if (num_channels == 4 && ext!=3 /*TIFF*/) continue;
    189 
    190                         ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_8U, num_channels, ext_from_int(ext).c_str());
    191                         Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
    192                         circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), std::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));
    193 
    194                         string img_path = cv::tempfile(ext_from_int(ext).c_str());
    195                         ts->printf(ts->LOG, "writing      image : %s\n", img_path.c_str());
    196                         imwrite(img_path, img);
    197 
    198                         ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str());
    199                         Mat img_test = imread(img_path, IMREAD_UNCHANGED);
    200 
    201                         if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);
    202 
    203                         CV_Assert(img.size() == img_test.size());
    204                         CV_Assert(img.type() == img_test.type());
    205                         CV_Assert(num_channels == img_test.channels());
    206 
    207                         double n = cvtest::norm(img, img_test, NORM_L2);
    208                         if ( n > 1.0)
    209                         {
    210                             ts->printf(ts->LOG, "norm = %f \n", n);
    211                             ts->set_failed_test_info(ts->FAIL_MISMATCH);
    212                         }
    213                     }
    214                 }
    215 
    216 #ifdef HAVE_JPEG
    217                 for (int num_channels = 1; num_channels <= 3; num_channels+=2)
    218                 {
    219                     // jpeg
    220                     ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_8U, num_channels, ".jpg");
    221                     Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
    222                     circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), std::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));
    223 
    224                     string filename = cv::tempfile(".jpg");
    225                     imwrite(filename, img);
    226                     ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str());
    227                     Mat img_test = imread(filename, IMREAD_UNCHANGED);
    228 
    229                     if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);
    230 
    231                     CV_Assert(img.size() == img_test.size());
    232                     CV_Assert(img.type() == img_test.type());
    233 
    234                     // JPEG format does not provide 100% accuracy
    235                     // using fuzzy image comparison
    236                     double n = cvtest::norm(img, img_test, NORM_L1);
    237                     double expected = 0.05 * img.size().area();
    238                     if ( n > expected)
    239                     {
    240                         ts->printf(ts->LOG, "norm = %f > expected = %f \n", n, expected);
    241                         ts->set_failed_test_info(ts->FAIL_MISMATCH);
    242                     }
    243                 }
    244 #endif
    245 
    246 #ifdef HAVE_TIFF
    247                 for (int num_channels = 1; num_channels <= 4; num_channels++)
    248                 {
    249                     if (num_channels == 2) continue;
    250                     // tiff
    251                     ts->printf(ts->LOG, "image type depth:%d   channels:%d   ext: %s\n", CV_16U, num_channels, ".tiff");
    252                     Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_16U, num_channels), Scalar::all(0));
    253                     circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), std::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));
    254 
    255                     string filename = cv::tempfile(".tiff");
    256                     imwrite(filename, img);
    257                     ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str());
    258                     Mat img_test = imread(filename, IMREAD_UNCHANGED);
    259 
    260                     if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);
    261 
    262                     CV_Assert(img.size() == img_test.size());
    263 
    264                     ts->printf(ts->LOG, "img      : %d ; %d \n", img.channels(), img.depth());
    265                     ts->printf(ts->LOG, "img_test : %d ; %d \n", img_test.channels(), img_test.depth());
    266 
    267                     CV_Assert(img.type() == img_test.type());
    268 
    269 
    270                     double n = cvtest::norm(img, img_test, NORM_L2);
    271                     if ( n > 1.0)
    272                     {
    273                         ts->printf(ts->LOG, "norm = %f \n", n);
    274                         ts->set_failed_test_info(ts->FAIL_MISMATCH);
    275                     }
    276                 }
    277 #endif
    278             }
    279         }
    280         catch(const cv::Exception & e)
    281         {
    282             ts->printf(ts->LOG, "Exception: %s\n" , e.what());
    283             ts->set_failed_test_info(ts->FAIL_MISMATCH);
    284         }
    285     }
    286 };
    287 
    288 class CV_GrfmtReadBMPRLE8Test : public cvtest::BaseTest
    289 {
    290 public:
    291     void run(int)
    292     {
    293         try
    294         {
    295             Mat rle = imread(string(ts->get_data_path()) + "readwrite/rle8.bmp");
    296             Mat bmp = imread(string(ts->get_data_path()) + "readwrite/ordinary.bmp");
    297             if (cvtest::norm(rle-bmp, NORM_L2)>1.e-10)
    298                 ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
    299         }
    300         catch(...)
    301         {
    302             ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
    303         }
    304         ts->set_failed_test_info(cvtest::TS::OK);
    305     }
    306 };
    307 
    308 
    309 #ifdef HAVE_PNG
    310 TEST(Imgcodecs_Image, write_big) { CV_GrfmtWriteBigImageTest test; test.safe_run(); }
    311 #endif
    312 
    313 TEST(Imgcodecs_Image, write_imageseq) { CV_GrfmtWriteSequenceImageTest test; test.safe_run(); }
    314 
    315 TEST(Imgcodecs_Image, read_bmp_rle8) { CV_GrfmtReadBMPRLE8Test test; test.safe_run(); }
    316 
    317 #ifdef HAVE_PNG
    318 class CV_GrfmtPNGEncodeTest : public cvtest::BaseTest
    319 {
    320 public:
    321     void run(int)
    322     {
    323         try
    324         {
    325             vector<uchar> buff;
    326             Mat im = Mat::zeros(1000,1000, CV_8U);
    327             //randu(im, 0, 256);
    328             vector<int> param;
    329             param.push_back(IMWRITE_PNG_COMPRESSION);
    330             param.push_back(3); //default(3) 0-9.
    331             cv::imencode(".png" ,im ,buff, param);
    332 
    333             // hangs
    334             Mat im2 = imdecode(buff,IMREAD_ANYDEPTH);
    335         }
    336         catch(...)
    337         {
    338             ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
    339         }
    340         ts->set_failed_test_info(cvtest::TS::OK);
    341     }
    342 };
    343 
    344 TEST(Imgcodecs_Image, encode_png) { CV_GrfmtPNGEncodeTest test; test.safe_run(); }
    345 
    346 TEST(Imgcodecs_ImreadVSCvtColor, regression)
    347 {
    348     cvtest::TS& ts = *cvtest::TS::ptr();
    349 
    350     const int MAX_MEAN_DIFF = 1;
    351     const int MAX_ABS_DIFF = 10;
    352 
    353     string imgName = string(ts.get_data_path()) + "/../cv/shared/lena.png";
    354     Mat original_image = imread(imgName);
    355     Mat gray_by_codec = imread(imgName, 0);
    356     Mat gray_by_cvt;
    357 
    358     cvtColor(original_image, gray_by_cvt, CV_BGR2GRAY);
    359 
    360     Mat diff;
    361     absdiff(gray_by_codec, gray_by_cvt, diff);
    362 
    363     double actual_avg_diff = (double)mean(diff)[0];
    364     double actual_maxval, actual_minval;
    365     minMaxLoc(diff, &actual_minval, &actual_maxval);
    366     //printf("actual avg = %g, actual maxdiff = %g, npixels = %d\n", actual_avg_diff, actual_maxval, (int)diff.total());
    367 
    368     EXPECT_LT(actual_avg_diff, MAX_MEAN_DIFF);
    369     EXPECT_LT(actual_maxval, MAX_ABS_DIFF);
    370 }
    371 
    372 //Test OpenCV issue 3075 is solved
    373 class CV_GrfmtReadPNGColorPaletteWithAlphaTest : public cvtest::BaseTest
    374 {
    375 public:
    376     void run(int)
    377     {
    378         try
    379         {
    380             // First Test : Read PNG with alpha, imread flag -1
    381             Mat img = imread(string(ts->get_data_path()) + "readwrite/color_palette_alpha.png",-1);
    382             if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
    383 
    384             ASSERT_TRUE(img.channels() == 4);
    385 
    386             unsigned char* img_data = img.ptr();
    387 
    388             // Verification first pixel is red in BGRA
    389             ASSERT_TRUE(img_data[0] == 0x00);
    390             ASSERT_TRUE(img_data[1] == 0x00);
    391             ASSERT_TRUE(img_data[2] == 0xFF);
    392             ASSERT_TRUE(img_data[3] == 0xFF);
    393 
    394             // Verification second pixel is red in BGRA
    395             ASSERT_TRUE(img_data[4] == 0x00);
    396             ASSERT_TRUE(img_data[5] == 0x00);
    397             ASSERT_TRUE(img_data[6] == 0xFF);
    398             ASSERT_TRUE(img_data[7] == 0xFF);
    399 
    400             // Second Test : Read PNG without alpha, imread flag -1
    401             img = imread(string(ts->get_data_path()) + "readwrite/color_palette_no_alpha.png",-1);
    402             if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
    403 
    404             ASSERT_TRUE(img.channels() == 3);
    405 
    406             img_data = img.ptr();
    407 
    408             // Verification first pixel is red in BGR
    409             ASSERT_TRUE(img_data[0] == 0x00);
    410             ASSERT_TRUE(img_data[1] == 0x00);
    411             ASSERT_TRUE(img_data[2] == 0xFF);
    412 
    413             // Verification second pixel is red in BGR
    414             ASSERT_TRUE(img_data[3] == 0x00);
    415             ASSERT_TRUE(img_data[4] == 0x00);
    416             ASSERT_TRUE(img_data[5] == 0xFF);
    417 
    418             // Third Test : Read PNG with alpha, imread flag 1
    419             img = imread(string(ts->get_data_path()) + "readwrite/color_palette_alpha.png",1);
    420             if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
    421 
    422             ASSERT_TRUE(img.channels() == 3);
    423 
    424             img_data = img.ptr();
    425 
    426             // Verification first pixel is red in BGR
    427             ASSERT_TRUE(img_data[0] == 0x00);
    428             ASSERT_TRUE(img_data[1] == 0x00);
    429             ASSERT_TRUE(img_data[2] == 0xFF);
    430 
    431             // Verification second pixel is red in BGR
    432             ASSERT_TRUE(img_data[3] == 0x00);
    433             ASSERT_TRUE(img_data[4] == 0x00);
    434             ASSERT_TRUE(img_data[5] == 0xFF);
    435 
    436             // Fourth Test : Read PNG without alpha, imread flag 1
    437             img = imread(string(ts->get_data_path()) + "readwrite/color_palette_no_alpha.png",1);
    438             if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
    439 
    440             ASSERT_TRUE(img.channels() == 3);
    441 
    442             img_data = img.ptr();
    443 
    444             // Verification first pixel is red in BGR
    445             ASSERT_TRUE(img_data[0] == 0x00);
    446             ASSERT_TRUE(img_data[1] == 0x00);
    447             ASSERT_TRUE(img_data[2] == 0xFF);
    448 
    449             // Verification second pixel is red in BGR
    450             ASSERT_TRUE(img_data[3] == 0x00);
    451             ASSERT_TRUE(img_data[4] == 0x00);
    452             ASSERT_TRUE(img_data[5] == 0xFF);
    453         }
    454         catch(...)
    455         {
    456             ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
    457     }
    458         ts->set_failed_test_info(cvtest::TS::OK);
    459     }
    460 };
    461 
    462 TEST(Imgcodecs_Image, read_png_color_palette_with_alpha) { CV_GrfmtReadPNGColorPaletteWithAlphaTest test; test.safe_run(); }
    463 #endif
    464 
    465 #ifdef HAVE_JPEG
    466 TEST(Imgcodecs_Jpeg, encode_empty)
    467 {
    468     cv::Mat img;
    469     std::vector<uchar> jpegImg;
    470 
    471     ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception);
    472 }
    473 
    474 TEST(Imgcodecs_Jpeg, encode_decode_progressive_jpeg)
    475 {
    476     cvtest::TS& ts = *cvtest::TS::ptr();
    477     string input = string(ts.get_data_path()) + "../cv/shared/lena.png";
    478     cv::Mat img = cv::imread(input);
    479     ASSERT_FALSE(img.empty());
    480 
    481     std::vector<int> params;
    482     params.push_back(IMWRITE_JPEG_PROGRESSIVE);
    483     params.push_back(1);
    484 
    485     string output_progressive = cv::tempfile(".jpg");
    486     EXPECT_NO_THROW(cv::imwrite(output_progressive, img, params));
    487     cv::Mat img_jpg_progressive = cv::imread(output_progressive);
    488 
    489     string output_normal = cv::tempfile(".jpg");
    490     EXPECT_NO_THROW(cv::imwrite(output_normal, img));
    491     cv::Mat img_jpg_normal = cv::imread(output_normal);
    492 
    493     EXPECT_EQ(0, cvtest::norm(img_jpg_progressive, img_jpg_normal, NORM_INF));
    494 
    495     remove(output_progressive.c_str());
    496 }
    497 
    498 TEST(Imgcodecs_Jpeg, encode_decode_optimize_jpeg)
    499 {
    500     cvtest::TS& ts = *cvtest::TS::ptr();
    501     string input = string(ts.get_data_path()) + "../cv/shared/lena.png";
    502     cv::Mat img = cv::imread(input);
    503     ASSERT_FALSE(img.empty());
    504 
    505     std::vector<int> params;
    506     params.push_back(IMWRITE_JPEG_OPTIMIZE);
    507     params.push_back(1);
    508 
    509     string output_optimized = cv::tempfile(".jpg");
    510     EXPECT_NO_THROW(cv::imwrite(output_optimized, img, params));
    511     cv::Mat img_jpg_optimized = cv::imread(output_optimized);
    512 
    513     string output_normal = cv::tempfile(".jpg");
    514     EXPECT_NO_THROW(cv::imwrite(output_normal, img));
    515     cv::Mat img_jpg_normal = cv::imread(output_normal);
    516 
    517     EXPECT_EQ(0, cvtest::norm(img_jpg_optimized, img_jpg_normal, NORM_INF));
    518 
    519     remove(output_optimized.c_str());
    520 }
    521 
    522 TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg)
    523 {
    524     cvtest::TS& ts = *cvtest::TS::ptr();
    525     string input = string(ts.get_data_path()) + "../cv/shared/lena.png";
    526     cv::Mat img = cv::imread(input);
    527     ASSERT_FALSE(img.empty());
    528 
    529     std::vector<int> params;
    530     params.push_back(IMWRITE_JPEG_RST_INTERVAL);
    531     params.push_back(1);
    532 
    533     string output_rst = cv::tempfile(".jpg");
    534     EXPECT_NO_THROW(cv::imwrite(output_rst, img, params));
    535     cv::Mat img_jpg_rst = cv::imread(output_rst);
    536 
    537     string output_normal = cv::tempfile(".jpg");
    538     EXPECT_NO_THROW(cv::imwrite(output_normal, img));
    539     cv::Mat img_jpg_normal = cv::imread(output_normal);
    540 
    541     EXPECT_EQ(0, cvtest::norm(img_jpg_rst, img_jpg_normal, NORM_INF));
    542 
    543     remove(output_rst.c_str());
    544 }
    545 
    546 #endif
    547 
    548 
    549 #ifdef HAVE_TIFF
    550 
    551 // these defines are used to resolve conflict between tiff.h and opencv2/core/types_c.h
    552 #define uint64 uint64_hack_
    553 #define int64 int64_hack_
    554 #include "tiff.h"
    555 
    556 #ifdef ANDROID
    557 // Test disabled as it uses a lot of memory.
    558 // It is killed with SIGKILL by out of memory killer.
    559 TEST(Imgcodecs_Tiff, DISABLED_decode_tile16384x16384)
    560 #else
    561 TEST(Imgcodecs_Tiff, decode_tile16384x16384)
    562 #endif
    563 {
    564     // see issue #2161
    565     cv::Mat big(16384, 16384, CV_8UC1, cv::Scalar::all(0));
    566     string file3 = cv::tempfile(".tiff");
    567     string file4 = cv::tempfile(".tiff");
    568 
    569     std::vector<int> params;
    570     params.push_back(TIFFTAG_ROWSPERSTRIP);
    571     params.push_back(big.rows);
    572     cv::imwrite(file4, big, params);
    573     cv::imwrite(file3, big.colRange(0, big.cols - 1), params);
    574     big.release();
    575 
    576     try
    577     {
    578         cv::imread(file3, IMREAD_UNCHANGED);
    579         EXPECT_NO_THROW(cv::imread(file4, IMREAD_UNCHANGED));
    580     }
    581     catch(const std::bad_alloc&)
    582     {
    583         // have no enough memory
    584     }
    585 
    586     remove(file3.c_str());
    587     remove(file4.c_str());
    588 }
    589 
    590 TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian)
    591 {
    592     // see issue #2601 "16-bit Grayscale TIFF Load Failures Due to Buffer Underflow and Endianness"
    593 
    594     // Setup data for two minimal 16-bit grayscale TIFF files in both endian formats
    595     uchar tiff_sample_data[2][86] = { {
    596         // Little endian
    597         0x49, 0x49, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xad, 0xde, 0xef, 0xbe, 0x06, 0x00, 0x00, 0x01,
    598         0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x00,
    599         0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00,
    600         0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01,
    601         0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00,
    602         0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }, {
    603         // Big endian
    604         0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x0c, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x06, 0x01, 0x00,
    605         0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00,
    606         0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10,
    607         0x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x11,
    608         0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x17, 0x00, 0x04, 0x00, 0x00,
    609         0x00, 0x01, 0x00, 0x00, 0x00, 0x04 }
    610         };
    611 
    612     // Test imread() for both a little endian TIFF and big endian TIFF
    613     for (int i = 0; i < 2; i++)
    614     {
    615         string filename = cv::tempfile(".tiff");
    616 
    617         // Write sample TIFF file
    618         FILE* fp = fopen(filename.c_str(), "wb");
    619         ASSERT_TRUE(fp != NULL);
    620         ASSERT_EQ((size_t)1, fwrite(tiff_sample_data, 86, 1, fp));
    621         fclose(fp);
    622 
    623         Mat img = imread(filename, IMREAD_UNCHANGED);
    624 
    625         EXPECT_EQ(1, img.rows);
    626         EXPECT_EQ(2, img.cols);
    627         EXPECT_EQ(CV_16U, img.type());
    628         EXPECT_EQ(sizeof(ushort), img.elemSize());
    629         EXPECT_EQ(1, img.channels());
    630         EXPECT_EQ(0xDEAD, img.at<ushort>(0,0));
    631         EXPECT_EQ(0xBEEF, img.at<ushort>(0,1));
    632 
    633         remove(filename.c_str());
    634     }
    635 }
    636 
    637 class CV_GrfmtReadTifTiledWithNotFullTiles: public cvtest::BaseTest
    638 {
    639 public:
    640     void run(int)
    641     {
    642         try
    643         {
    644             /* see issue #3472 - dealing with tiled images where the tile size is
    645              * not a multiple of image size.
    646              * The tiled images were created with 'convert' from ImageMagick,
    647              * using the command 'convert <input> -define tiff:tile-geometry=128x128 -depth [8|16] <output>
    648              * Note that the conversion to 16 bits expands the range from 0-255 to 0-255*255,
    649              * so the test converts back but rounding errors cause small differences.
    650              */
    651             cv::Mat img = imread(string(ts->get_data_path()) + "readwrite/non_tiled.tif",-1);
    652             if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
    653             ASSERT_TRUE(img.channels() == 3);
    654             cv::Mat tiled8 = imread(string(ts->get_data_path()) + "readwrite/tiled_8.tif", -1);
    655             if (tiled8.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
    656             ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, tiled8);
    657 
    658             cv::Mat tiled16 = imread(string(ts->get_data_path()) + "readwrite/tiled_16.tif", -1);
    659             if (tiled16.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
    660             ASSERT_TRUE(tiled16.elemSize() == 6);
    661             tiled16.convertTo(tiled8, CV_8UC3, 1./256.);
    662             ASSERT_PRED_FORMAT2(cvtest::MatComparator(2, 0), img, tiled8);
    663             // What about 32, 64 bit?
    664         }
    665         catch(...)
    666         {
    667             ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
    668         }
    669         ts->set_failed_test_info(cvtest::TS::OK);
    670     }
    671 };
    672 
    673 TEST(Imgcodecs_Tiff, decode_tile_remainder)
    674 {
    675     CV_GrfmtReadTifTiledWithNotFullTiles test; test.safe_run();
    676 }
    677 
    678 TEST(Imgcodecs_Tiff, decode_infinite_rowsperstrip)
    679 {
    680     const uchar sample_data[142] = {
    681         0x49, 0x49, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x56, 0x54,
    682         0x56, 0x5a, 0x59, 0x55, 0x5a, 0x00, 0x0a, 0x00, 0x00, 0x01,
    683         0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    684         0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00,
    685         0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
    686         0x08, 0x00, 0x00, 0x00, 0x03, 0x01, 0x03, 0x00, 0x01, 0x00,
    687         0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00,
    688         0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01,
    689         0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
    690         0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
    691         0x00, 0x00, 0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
    692         0xff, 0xff, 0xff, 0xff, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00,
    693         0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x03, 0x00,
    694         0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
    695         0x00, 0x00
    696     };
    697 
    698     const string filename = cv::tempfile(".tiff");
    699     std::ofstream outfile(filename.c_str(), std::ofstream::binary);
    700     outfile.write(reinterpret_cast<const char *>(sample_data), sizeof sample_data);
    701     outfile.close();
    702 
    703     EXPECT_NO_THROW(cv::imread(filename, IMREAD_UNCHANGED));
    704 
    705     remove(filename.c_str());
    706 }
    707 
    708 class CV_GrfmtReadTifMultiPage : public cvtest::BaseTest
    709 {
    710 private:
    711     void compare(int flags)
    712     {
    713         const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/";
    714         const int page_count = 6;
    715 
    716         vector<Mat> pages;
    717         bool res = imreadmulti(folder + "multipage.tif", pages, flags);
    718         ASSERT_TRUE(res == true);
    719         ASSERT_EQ(static_cast<size_t>(page_count), pages.size());
    720 
    721         for (int i = 0; i < page_count; i++)
    722         {
    723             char buffer[256];
    724             sprintf(buffer, "%smultipage_p%d.tif", folder.c_str(), i + 1);
    725             const string filepath(buffer);
    726             const Mat page = imread(filepath, flags);
    727             ASSERT_TRUE(mats_equal(page, pages[i]));
    728         }
    729     }
    730 
    731 public:
    732     void run(int)
    733     {
    734         compare(IMREAD_UNCHANGED);
    735         compare(IMREAD_GRAYSCALE);
    736         compare(IMREAD_COLOR);
    737         compare(IMREAD_ANYDEPTH);
    738         compare(IMREAD_ANYCOLOR);
    739         // compare(IMREAD_LOAD_GDAL); // GDAL does not support multi-page TIFFs
    740     }
    741 };
    742 
    743 TEST(Imgcodecs_Tiff, decode_multipage)
    744 {
    745     CV_GrfmtReadTifMultiPage test; test.safe_run();
    746 }
    747 
    748 #endif
    749 
    750 #ifdef HAVE_WEBP
    751 
    752 TEST(Imgcodecs_WebP, encode_decode_lossless_webp)
    753 {
    754     cvtest::TS& ts = *cvtest::TS::ptr();
    755     string input = string(ts.get_data_path()) + "../cv/shared/lena.png";
    756     cv::Mat img = cv::imread(input);
    757     ASSERT_FALSE(img.empty());
    758 
    759     string output = cv::tempfile(".webp");
    760     EXPECT_NO_THROW(cv::imwrite(output, img)); // lossless
    761 
    762     cv::Mat img_webp = cv::imread(output);
    763 
    764     std::vector<unsigned char> buf;
    765 
    766     FILE * wfile = NULL;
    767 
    768     wfile = fopen(output.c_str(), "rb");
    769     if (wfile != NULL)
    770     {
    771         fseek(wfile, 0, SEEK_END);
    772         size_t wfile_size = ftell(wfile);
    773         fseek(wfile, 0, SEEK_SET);
    774 
    775         buf.resize(wfile_size);
    776 
    777         size_t data_size = fread(&buf[0], 1, wfile_size, wfile);
    778 
    779         if(wfile)
    780         {
    781             fclose(wfile);
    782         }
    783 
    784         if (data_size != wfile_size)
    785         {
    786             EXPECT_TRUE(false);
    787         }
    788     }
    789 
    790     remove(output.c_str());
    791 
    792     cv::Mat decode = cv::imdecode(buf, IMREAD_COLOR);
    793     ASSERT_FALSE(decode.empty());
    794     EXPECT_TRUE(cvtest::norm(decode, img_webp, NORM_INF) == 0);
    795 
    796     ASSERT_FALSE(img_webp.empty());
    797 
    798     EXPECT_TRUE(cvtest::norm(img, img_webp, NORM_INF) == 0);
    799 }
    800 
    801 TEST(Imgcodecs_WebP, encode_decode_lossy_webp)
    802 {
    803     cvtest::TS& ts = *cvtest::TS::ptr();
    804     std::string input = std::string(ts.get_data_path()) + "../cv/shared/lena.png";
    805     cv::Mat img = cv::imread(input);
    806     ASSERT_FALSE(img.empty());
    807 
    808     for(int q = 100; q>=0; q-=20)
    809     {
    810         std::vector<int> params;
    811         params.push_back(IMWRITE_WEBP_QUALITY);
    812         params.push_back(q);
    813         string output = cv::tempfile(".webp");
    814 
    815         EXPECT_NO_THROW(cv::imwrite(output, img, params));
    816         cv::Mat img_webp = cv::imread(output);
    817         remove(output.c_str());
    818         EXPECT_FALSE(img_webp.empty());
    819         EXPECT_EQ(3,   img_webp.channels());
    820         EXPECT_EQ(512, img_webp.cols);
    821         EXPECT_EQ(512, img_webp.rows);
    822     }
    823 }
    824 
    825 TEST(Imgcodecs_WebP, encode_decode_with_alpha_webp)
    826 {
    827     cvtest::TS& ts = *cvtest::TS::ptr();
    828     std::string input = std::string(ts.get_data_path()) + "../cv/shared/lena.png";
    829     cv::Mat img = cv::imread(input);
    830     ASSERT_FALSE(img.empty());
    831 
    832     std::vector<cv::Mat> imgs;
    833     cv::split(img, imgs);
    834     imgs.push_back(cv::Mat(imgs[0]));
    835     imgs[imgs.size() - 1] = cv::Scalar::all(128);
    836     cv::merge(imgs, img);
    837 
    838     string output = cv::tempfile(".webp");
    839 
    840     EXPECT_NO_THROW(cv::imwrite(output, img));
    841     cv::Mat img_webp = cv::imread(output);
    842     remove(output.c_str());
    843     EXPECT_FALSE(img_webp.empty());
    844     EXPECT_EQ(4,   img_webp.channels());
    845     EXPECT_EQ(512, img_webp.cols);
    846     EXPECT_EQ(512, img_webp.rows);
    847 }
    848 
    849 #endif
    850 
    851 TEST(Imgcodecs_Hdr, regression)
    852 {
    853     string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/";
    854     string name_rle = folder + "rle.hdr";
    855     string name_no_rle = folder + "no_rle.hdr";
    856     Mat img_rle = imread(name_rle, -1);
    857     ASSERT_FALSE(img_rle.empty()) << "Could not open " << name_rle;
    858     Mat img_no_rle = imread(name_no_rle, -1);
    859     ASSERT_FALSE(img_no_rle.empty()) << "Could not open " << name_no_rle;
    860 
    861     double min = 0.0, max = 1.0;
    862     minMaxLoc(abs(img_rle - img_no_rle), &min, &max);
    863     ASSERT_FALSE(max > DBL_EPSILON);
    864     string tmp_file_name = tempfile(".hdr");
    865     vector<int>param(1);
    866     for(int i = 0; i < 2; i++) {
    867         param[0] = i;
    868         imwrite(tmp_file_name, img_rle, param);
    869         Mat written_img = imread(tmp_file_name, -1);
    870         ASSERT_FALSE(written_img.empty()) << "Could not open " << tmp_file_name;
    871         minMaxLoc(abs(img_rle - written_img), &min, &max);
    872         ASSERT_FALSE(max > DBL_EPSILON);
    873     }
    874 }
    875