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