test_tiff.cpp 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html
  4. #include "test_precomp.hpp"
  5. #include "opencv2/core/utils/logger.hpp"
  6. #include "opencv2/core/utils/configuration.private.hpp"
  7. namespace opencv_test { namespace {
  8. #ifdef HAVE_TIFF
  9. #ifdef __ANDROID__
  10. // Test disabled as it uses a lot of memory.
  11. // It is killed with SIGKILL by out of memory killer.
  12. TEST(Imgcodecs_Tiff, DISABLED_decode_tile16384x16384)
  13. #else
  14. TEST(Imgcodecs_Tiff, decode_tile16384x16384)
  15. #endif
  16. {
  17. // see issue #2161
  18. cv::Mat big(16384, 16384, CV_8UC1, cv::Scalar::all(0));
  19. string file3 = cv::tempfile(".tiff");
  20. string file4 = cv::tempfile(".tiff");
  21. std::vector<int> params;
  22. params.push_back(IMWRITE_TIFF_ROWSPERSTRIP);
  23. params.push_back(big.rows);
  24. EXPECT_NO_THROW(cv::imwrite(file4, big, params));
  25. EXPECT_NO_THROW(cv::imwrite(file3, big.colRange(0, big.cols - 1), params));
  26. big.release();
  27. try
  28. {
  29. cv::imread(file3, IMREAD_UNCHANGED);
  30. EXPECT_NO_THROW(cv::imread(file4, IMREAD_UNCHANGED));
  31. }
  32. catch(const std::bad_alloc&)
  33. {
  34. // not enough memory
  35. }
  36. EXPECT_EQ(0, remove(file3.c_str()));
  37. EXPECT_EQ(0, remove(file4.c_str()));
  38. }
  39. //==================================================================================================
  40. // See https://github.com/opencv/opencv/issues/22388
  41. typedef tuple< uint64_t, perf::MatType, ImreadModes > Bufsize_and_Type;
  42. typedef testing::TestWithParam<Bufsize_and_Type> Imgcodecs_Tiff_decode_Huge;
  43. TEST_P(Imgcodecs_Tiff_decode_Huge, regression)
  44. {
  45. // Get test parameters
  46. const uint64_t buffer_size = get<0>(GetParam());
  47. const perf::MatType mat_type = get<1>(GetParam());
  48. const int imread_mode = get<2>(GetParam());
  49. // Detect data file
  50. const string req_filename = cv::format("readwrite/huge-tiff/%s_%zu.tif", typeToString(mat_type).c_str(), (size_t)buffer_size);
  51. const string filename = findDataFile( req_filename );
  52. // Preparation process for test
  53. {
  54. // Convert from mat_type and buffer_size to tiff file information.
  55. const uint64_t width = 32768;
  56. int ncn = CV_MAT_CN(mat_type);
  57. int depth = ( CV_MAT_DEPTH(mat_type) == CV_16U) ? 2 : 1; // 16bit or 8 bit
  58. const uint64_t height = (uint64_t) buffer_size / width / ncn / depth;
  59. const uint64_t base_scanline_size = (uint64_t) width * ncn * depth;
  60. const uint64_t base_strip_size = (uint64_t) base_scanline_size * height;
  61. // To avoid exception about pixel size, check it.
  62. static const size_t CV_IO_MAX_IMAGE_PIXELS = utils::getConfigurationParameterSizeT("OPENCV_IO_MAX_IMAGE_PIXELS", 1 << 30);
  63. uint64_t pixels = (uint64_t) width * height;
  64. if ( pixels > CV_IO_MAX_IMAGE_PIXELS )
  65. {
  66. throw SkipTestException( cv::format("Test is skipped( pixels(%zu) > CV_IO_MAX_IMAGE_PIXELS(%zu) )",
  67. (size_t)pixels, CV_IO_MAX_IMAGE_PIXELS) );
  68. }
  69. // If buffer_size >= 1GB * 95%, TIFFReadScanline() is used.
  70. const uint64_t BUFFER_SIZE_LIMIT_FOR_READS_CANLINE = (uint64_t) 1024*1024*1024*95/100;
  71. const bool doReadScanline = ( base_strip_size >= BUFFER_SIZE_LIMIT_FOR_READS_CANLINE );
  72. // Update ncn and depth for destination Mat.
  73. switch ( imread_mode )
  74. {
  75. case IMREAD_UNCHANGED:
  76. break;
  77. case IMREAD_GRAYSCALE:
  78. ncn = 1;
  79. depth = 1;
  80. break;
  81. case IMREAD_GRAYSCALE | IMREAD_ANYDEPTH:
  82. ncn = 1;
  83. break;
  84. case IMREAD_GRAYSCALE | IMREAD_ANYCOLOR:
  85. ncn = (ncn == 1)?1:3;
  86. depth = 1;
  87. break;
  88. case IMREAD_GRAYSCALE | IMREAD_ANYCOLOR | IMREAD_ANYDEPTH:
  89. ncn = (ncn == 1)?1:3;
  90. break;
  91. case IMREAD_COLOR:
  92. ncn = 3;
  93. depth = 1;
  94. break;
  95. case IMREAD_COLOR | IMREAD_ANYDEPTH:
  96. ncn = 3;
  97. break;
  98. case IMREAD_COLOR | IMREAD_ANYCOLOR:
  99. ncn = 3;
  100. depth = 1;
  101. break;
  102. case IMREAD_COLOR | IMREAD_ANYDEPTH | IMREAD_ANYCOLOR:
  103. ncn = 3;
  104. break;
  105. default:
  106. break;
  107. }
  108. // Memory usage for Destination Mat
  109. const uint64_t memory_usage_cvmat = (uint64_t) width * ncn * depth * height;
  110. // Memory usage for Work memory in libtiff.
  111. uint64_t memory_usage_tiff = 0;
  112. if ( ( depth == 1 ) && ( !doReadScanline ) )
  113. {
  114. // TIFFReadRGBA*() request to allocate RGBA(32bit) buffer.
  115. memory_usage_tiff = (uint64_t)
  116. width *
  117. 4 * // ncn = RGBA
  118. 1 * // dst_bpp = 8 bpp
  119. height;
  120. }
  121. else
  122. {
  123. // TIFFReadEncodedStrip() or TIFFReadScanline() request to allocate strip memory.
  124. memory_usage_tiff = base_strip_size;
  125. }
  126. // Memory usage for Work memory in imgcodec/grfmt_tiff.cpp
  127. const uint64_t memory_usage_work =
  128. ( doReadScanline ) ? base_scanline_size // for TIFFReadScanline()
  129. : base_strip_size; // for TIFFReadRGBA*() or TIFFReadEncodedStrip()
  130. // Total memory usage.
  131. const uint64_t memory_usage_total =
  132. memory_usage_cvmat + // Destination Mat
  133. memory_usage_tiff + // Work memory in libtiff
  134. memory_usage_work; // Work memory in imgcodecs
  135. // Output memory usage log.
  136. CV_LOG_DEBUG(NULL, cv::format("OpenCV TIFF-test: memory usage info : mat(%zu), libtiff(%zu), work(%zu) -> total(%zu)",
  137. (size_t)memory_usage_cvmat, (size_t)memory_usage_tiff, (size_t)memory_usage_work, (size_t)memory_usage_total) );
  138. // Add test tags.
  139. if ( memory_usage_total >= (uint64_t) 6144 * 1024 * 1024 )
  140. {
  141. applyTestTag( CV_TEST_TAG_MEMORY_14GB, CV_TEST_TAG_VERYLONG );
  142. }
  143. else if ( memory_usage_total >= (uint64_t) 2048 * 1024 * 1024 )
  144. {
  145. applyTestTag( CV_TEST_TAG_MEMORY_6GB, CV_TEST_TAG_VERYLONG );
  146. }
  147. else if ( memory_usage_total >= (uint64_t) 1024 * 1024 * 1024 )
  148. {
  149. applyTestTag( CV_TEST_TAG_MEMORY_2GB, CV_TEST_TAG_LONG );
  150. }
  151. else if ( memory_usage_total >= (uint64_t) 512 * 1024 * 1024 )
  152. {
  153. applyTestTag( CV_TEST_TAG_MEMORY_1GB );
  154. }
  155. else if ( memory_usage_total >= (uint64_t) 200 * 1024 * 1024 )
  156. {
  157. applyTestTag( CV_TEST_TAG_MEMORY_512MB );
  158. }
  159. else
  160. {
  161. // do nothing.
  162. }
  163. }
  164. // TEST Main
  165. cv::Mat img;
  166. ASSERT_NO_THROW( img = cv::imread(filename, imread_mode) );
  167. ASSERT_FALSE(img.empty());
  168. /**
  169. * Test marker pixels at each corners.
  170. *
  171. * 0xAn,0x00 ... 0x00, 0xBn
  172. * 0x00,0x00 ... 0x00, 0x00
  173. * : : : :
  174. * 0x00,0x00 ... 0x00, 0x00
  175. * 0xCn,0x00 .., 0x00, 0xDn
  176. *
  177. */
  178. #define MAKE_FLAG(from_type, to_type) (((uint64_t)from_type << 32 ) | to_type )
  179. switch ( MAKE_FLAG(mat_type, img.type() ) )
  180. {
  181. // GRAY TO GRAY
  182. case MAKE_FLAG(CV_8UC1, CV_8UC1):
  183. case MAKE_FLAG(CV_16UC1, CV_8UC1):
  184. EXPECT_EQ( 0xA0, img.at<uchar>(0, 0) );
  185. EXPECT_EQ( 0xB0, img.at<uchar>(0, img.cols-1) );
  186. EXPECT_EQ( 0xC0, img.at<uchar>(img.rows-1, 0) );
  187. EXPECT_EQ( 0xD0, img.at<uchar>(img.rows-1, img.cols-1) );
  188. break;
  189. // RGB/RGBA TO BGR
  190. case MAKE_FLAG(CV_8UC3, CV_8UC3):
  191. case MAKE_FLAG(CV_8UC4, CV_8UC3):
  192. case MAKE_FLAG(CV_16UC3, CV_8UC3):
  193. case MAKE_FLAG(CV_16UC4, CV_8UC3):
  194. EXPECT_EQ( 0xA2, img.at<Vec3b>(0, 0) [0] );
  195. EXPECT_EQ( 0xA1, img.at<Vec3b>(0, 0) [1] );
  196. EXPECT_EQ( 0xA0, img.at<Vec3b>(0, 0) [2] );
  197. EXPECT_EQ( 0xB2, img.at<Vec3b>(0, img.cols-1)[0] );
  198. EXPECT_EQ( 0xB1, img.at<Vec3b>(0, img.cols-1)[1] );
  199. EXPECT_EQ( 0xB0, img.at<Vec3b>(0, img.cols-1)[2] );
  200. EXPECT_EQ( 0xC2, img.at<Vec3b>(img.rows-1, 0) [0] );
  201. EXPECT_EQ( 0xC1, img.at<Vec3b>(img.rows-1, 0) [1] );
  202. EXPECT_EQ( 0xC0, img.at<Vec3b>(img.rows-1, 0) [2] );
  203. EXPECT_EQ( 0xD2, img.at<Vec3b>(img.rows-1, img.cols-1)[0] );
  204. EXPECT_EQ( 0xD1, img.at<Vec3b>(img.rows-1, img.cols-1)[1] );
  205. EXPECT_EQ( 0xD0, img.at<Vec3b>(img.rows-1, img.cols-1)[2] );
  206. break;
  207. // RGBA TO BGRA
  208. case MAKE_FLAG(CV_8UC4, CV_8UC4):
  209. case MAKE_FLAG(CV_16UC4, CV_8UC4):
  210. EXPECT_EQ( 0xA2, img.at<Vec4b>(0, 0) [0] );
  211. EXPECT_EQ( 0xA1, img.at<Vec4b>(0, 0) [1] );
  212. EXPECT_EQ( 0xA0, img.at<Vec4b>(0, 0) [2] );
  213. EXPECT_EQ( 0xA3, img.at<Vec4b>(0, 0) [3] );
  214. EXPECT_EQ( 0xB2, img.at<Vec4b>(0, img.cols-1)[0] );
  215. EXPECT_EQ( 0xB1, img.at<Vec4b>(0, img.cols-1)[1] );
  216. EXPECT_EQ( 0xB0, img.at<Vec4b>(0, img.cols-1)[2] );
  217. EXPECT_EQ( 0xB3, img.at<Vec4b>(0, img.cols-1)[3] );
  218. EXPECT_EQ( 0xC2, img.at<Vec4b>(img.rows-1, 0) [0] );
  219. EXPECT_EQ( 0xC1, img.at<Vec4b>(img.rows-1, 0) [1] );
  220. EXPECT_EQ( 0xC0, img.at<Vec4b>(img.rows-1, 0) [2] );
  221. EXPECT_EQ( 0xC3, img.at<Vec4b>(img.rows-1, 0) [3] );
  222. EXPECT_EQ( 0xD2, img.at<Vec4b>(img.rows-1, img.cols-1)[0] );
  223. EXPECT_EQ( 0xD1, img.at<Vec4b>(img.rows-1, img.cols-1)[1] );
  224. EXPECT_EQ( 0xD0, img.at<Vec4b>(img.rows-1, img.cols-1)[2] );
  225. EXPECT_EQ( 0xD3, img.at<Vec4b>(img.rows-1, img.cols-1)[3] );
  226. break;
  227. // RGB/RGBA to GRAY
  228. case MAKE_FLAG(CV_8UC3, CV_8UC1):
  229. case MAKE_FLAG(CV_8UC4, CV_8UC1):
  230. case MAKE_FLAG(CV_16UC3, CV_8UC1):
  231. case MAKE_FLAG(CV_16UC4, CV_8UC1):
  232. EXPECT_LE( 0xA0, img.at<uchar>(0, 0) );
  233. EXPECT_GE( 0xA2, img.at<uchar>(0, 0) );
  234. EXPECT_LE( 0xB0, img.at<uchar>(0, img.cols-1) );
  235. EXPECT_GE( 0xB2, img.at<uchar>(0, img.cols-1) );
  236. EXPECT_LE( 0xC0, img.at<uchar>(img.rows-1, 0) );
  237. EXPECT_GE( 0xC2, img.at<uchar>(img.rows-1, 0) );
  238. EXPECT_LE( 0xD0, img.at<uchar>(img.rows-1, img.cols-1) );
  239. EXPECT_GE( 0xD2, img.at<uchar>(img.rows-1, img.cols-1) );
  240. break;
  241. // GRAY to BGR
  242. case MAKE_FLAG(CV_8UC1, CV_8UC3):
  243. case MAKE_FLAG(CV_16UC1, CV_8UC3):
  244. EXPECT_EQ( 0xA0, img.at<Vec3b>(0, 0) [0] );
  245. EXPECT_EQ( 0xB0, img.at<Vec3b>(0, img.cols-1)[0] );
  246. EXPECT_EQ( 0xC0, img.at<Vec3b>(img.rows-1, 0) [0] );
  247. EXPECT_EQ( 0xD0, img.at<Vec3b>(img.rows-1, img.cols-1)[0] );
  248. // R==G==B
  249. EXPECT_EQ( img.at<Vec3b>(0, 0) [0], img.at<Vec3b>(0, 0) [1] );
  250. EXPECT_EQ( img.at<Vec3b>(0, 0) [0], img.at<Vec3b>(0, 0) [2] );
  251. EXPECT_EQ( img.at<Vec3b>(0, img.cols-1) [0], img.at<Vec3b>(0, img.cols-1)[1] );
  252. EXPECT_EQ( img.at<Vec3b>(0, img.cols-1) [0], img.at<Vec3b>(0, img.cols-1)[2] );
  253. EXPECT_EQ( img.at<Vec3b>(img.rows-1, 0) [0], img.at<Vec3b>(img.rows-1, 0) [1] );
  254. EXPECT_EQ( img.at<Vec3b>(img.rows-1, 0) [0], img.at<Vec3b>(img.rows-1, 0) [2] );
  255. EXPECT_EQ( img.at<Vec3b>(img.rows-1, img.cols-1) [0], img.at<Vec3b>(img.rows-1, img.cols-1)[1] );
  256. EXPECT_EQ( img.at<Vec3b>(img.rows-1, img.cols-1) [0], img.at<Vec3b>(img.rows-1, img.cols-1)[2] );
  257. break;
  258. // GRAY TO GRAY
  259. case MAKE_FLAG(CV_16UC1, CV_16UC1):
  260. EXPECT_EQ( 0xA090, img.at<ushort>(0, 0) );
  261. EXPECT_EQ( 0xB080, img.at<ushort>(0, img.cols-1) );
  262. EXPECT_EQ( 0xC070, img.at<ushort>(img.rows-1, 0) );
  263. EXPECT_EQ( 0xD060, img.at<ushort>(img.rows-1, img.cols-1) );
  264. break;
  265. // RGB/RGBA TO BGR
  266. case MAKE_FLAG(CV_16UC3, CV_16UC3):
  267. case MAKE_FLAG(CV_16UC4, CV_16UC3):
  268. EXPECT_EQ( 0xA292, img.at<Vec3w>(0, 0) [0] );
  269. EXPECT_EQ( 0xA191, img.at<Vec3w>(0, 0) [1] );
  270. EXPECT_EQ( 0xA090, img.at<Vec3w>(0, 0) [2] );
  271. EXPECT_EQ( 0xB282, img.at<Vec3w>(0, img.cols-1)[0] );
  272. EXPECT_EQ( 0xB181, img.at<Vec3w>(0, img.cols-1)[1] );
  273. EXPECT_EQ( 0xB080, img.at<Vec3w>(0, img.cols-1)[2] );
  274. EXPECT_EQ( 0xC272, img.at<Vec3w>(img.rows-1, 0) [0] );
  275. EXPECT_EQ( 0xC171, img.at<Vec3w>(img.rows-1, 0) [1] );
  276. EXPECT_EQ( 0xC070, img.at<Vec3w>(img.rows-1, 0) [2] );
  277. EXPECT_EQ( 0xD262, img.at<Vec3w>(img.rows-1, img.cols-1)[0] );
  278. EXPECT_EQ( 0xD161, img.at<Vec3w>(img.rows-1, img.cols-1)[1] );
  279. EXPECT_EQ( 0xD060, img.at<Vec3w>(img.rows-1, img.cols-1)[2] );
  280. break;
  281. // RGBA TO RGBA
  282. case MAKE_FLAG(CV_16UC4, CV_16UC4):
  283. EXPECT_EQ( 0xA292, img.at<Vec4w>(0, 0) [0] );
  284. EXPECT_EQ( 0xA191, img.at<Vec4w>(0, 0) [1] );
  285. EXPECT_EQ( 0xA090, img.at<Vec4w>(0, 0) [2] );
  286. EXPECT_EQ( 0xA393, img.at<Vec4w>(0, 0) [3] );
  287. EXPECT_EQ( 0xB282, img.at<Vec4w>(0, img.cols-1)[0] );
  288. EXPECT_EQ( 0xB181, img.at<Vec4w>(0, img.cols-1)[1] );
  289. EXPECT_EQ( 0xB080, img.at<Vec4w>(0, img.cols-1)[2] );
  290. EXPECT_EQ( 0xB383, img.at<Vec4w>(0, img.cols-1)[3] );
  291. EXPECT_EQ( 0xC272, img.at<Vec4w>(img.rows-1, 0) [0] );
  292. EXPECT_EQ( 0xC171, img.at<Vec4w>(img.rows-1, 0) [1] );
  293. EXPECT_EQ( 0xC070, img.at<Vec4w>(img.rows-1, 0) [2] );
  294. EXPECT_EQ( 0xC373, img.at<Vec4w>(img.rows-1, 0) [3] );
  295. EXPECT_EQ( 0xD262, img.at<Vec4w>(img.rows-1,img.cols-1) [0] );
  296. EXPECT_EQ( 0xD161, img.at<Vec4w>(img.rows-1,img.cols-1) [1] );
  297. EXPECT_EQ( 0xD060, img.at<Vec4w>(img.rows-1,img.cols-1) [2] );
  298. EXPECT_EQ( 0xD363, img.at<Vec4w>(img.rows-1,img.cols-1) [3] );
  299. break;
  300. // RGB/RGBA to GRAY
  301. case MAKE_FLAG(CV_16UC3, CV_16UC1):
  302. case MAKE_FLAG(CV_16UC4, CV_16UC1):
  303. EXPECT_LE( 0xA090, img.at<ushort>(0, 0) );
  304. EXPECT_GE( 0xA292, img.at<ushort>(0, 0) );
  305. EXPECT_LE( 0xB080, img.at<ushort>(0, img.cols-1) );
  306. EXPECT_GE( 0xB282, img.at<ushort>(0, img.cols-1) );
  307. EXPECT_LE( 0xC070, img.at<ushort>(img.rows-1, 0) );
  308. EXPECT_GE( 0xC272, img.at<ushort>(img.rows-1, 0) );
  309. EXPECT_LE( 0xD060, img.at<ushort>(img.rows-1, img.cols-1) );
  310. EXPECT_GE( 0xD262, img.at<ushort>(img.rows-1, img.cols-1) );
  311. break;
  312. // GRAY to RGB
  313. case MAKE_FLAG(CV_16UC1, CV_16UC3):
  314. EXPECT_EQ( 0xA090, img.at<Vec3w>(0, 0) [0] );
  315. EXPECT_EQ( 0xB080, img.at<Vec3w>(0, img.cols-1)[0] );
  316. EXPECT_EQ( 0xC070, img.at<Vec3w>(img.rows-1, 0) [0] );
  317. EXPECT_EQ( 0xD060, img.at<Vec3w>(img.rows-1, img.cols-1)[0] );
  318. // R==G==B
  319. EXPECT_EQ( img.at<Vec3w>(0, 0) [0], img.at<Vec3w>(0, 0) [1] );
  320. EXPECT_EQ( img.at<Vec3w>(0, 0) [0], img.at<Vec3w>(0, 0) [2] );
  321. EXPECT_EQ( img.at<Vec3w>(0, img.cols-1) [0], img.at<Vec3w>(0, img.cols-1)[1] );
  322. EXPECT_EQ( img.at<Vec3w>(0, img.cols-1) [0], img.at<Vec3w>(0, img.cols-1)[2] );
  323. EXPECT_EQ( img.at<Vec3w>(img.rows-1, 0) [0], img.at<Vec3w>(img.rows-1, 0) [1] );
  324. EXPECT_EQ( img.at<Vec3w>(img.rows-1, 0) [0], img.at<Vec3w>(img.rows-1, 0) [2] );
  325. EXPECT_EQ( img.at<Vec3w>(img.rows-1, img.cols-1) [0], img.at<Vec3w>(img.rows-1, img.cols-1)[1] );
  326. EXPECT_EQ( img.at<Vec3w>(img.rows-1, img.cols-1) [0], img.at<Vec3w>(img.rows-1, img.cols-1)[2] );
  327. break;
  328. // No supported.
  329. // (1) 8bit to 16bit
  330. case MAKE_FLAG(CV_8UC1, CV_16UC1):
  331. case MAKE_FLAG(CV_8UC1, CV_16UC3):
  332. case MAKE_FLAG(CV_8UC1, CV_16UC4):
  333. case MAKE_FLAG(CV_8UC3, CV_16UC1):
  334. case MAKE_FLAG(CV_8UC3, CV_16UC3):
  335. case MAKE_FLAG(CV_8UC3, CV_16UC4):
  336. case MAKE_FLAG(CV_8UC4, CV_16UC1):
  337. case MAKE_FLAG(CV_8UC4, CV_16UC3):
  338. case MAKE_FLAG(CV_8UC4, CV_16UC4):
  339. // (2) GRAY/RGB TO RGBA
  340. case MAKE_FLAG(CV_8UC1, CV_8UC4):
  341. case MAKE_FLAG(CV_8UC3, CV_8UC4):
  342. case MAKE_FLAG(CV_16UC1, CV_8UC4):
  343. case MAKE_FLAG(CV_16UC3, CV_8UC4):
  344. case MAKE_FLAG(CV_16UC1, CV_16UC4):
  345. case MAKE_FLAG(CV_16UC3, CV_16UC4):
  346. default:
  347. FAIL() << cv::format("Unknown test pattern: from = ( %d, %d) to = ( %d, %d )",
  348. (int)CV_MAT_CN(mat_type ), ( CV_MAT_DEPTH(mat_type )==CV_16U)?16:8,
  349. (int)CV_MAT_CN(img.type() ), ( CV_MAT_DEPTH(img.type() )==CV_16U)?16:8);
  350. break;
  351. }
  352. #undef MAKE_FLAG
  353. }
  354. // Basic Test
  355. const Bufsize_and_Type Imgcodecs_Tiff_decode_Huge_list_basic[] =
  356. {
  357. make_tuple<uint64_t, perf::MatType, ImreadModes>( 1073479680ull, CV_8UC1, IMREAD_COLOR ),
  358. make_tuple<uint64_t, perf::MatType, ImreadModes>( 2147483648ull, CV_16UC4, IMREAD_COLOR ),
  359. };
  360. INSTANTIATE_TEST_CASE_P(Imgcodecs_Tiff, Imgcodecs_Tiff_decode_Huge,
  361. testing::ValuesIn( Imgcodecs_Tiff_decode_Huge_list_basic )
  362. );
  363. // Full Test
  364. // This full test is disabled in default, following steps are required to run.
  365. // (1) replace "DISABLED_Imgcodecs_Tiff_Full" to "Imgcodecs_Tiff_Full" and rebuild opencv_test_imgcodecs.
  366. // (2) set "OPENCV_IO_MAX_IMAGE_PIXELS=2147483648" in environment variable.
  367. // (3) run "./bin/opencv_test_imgcodecs --test_tag_enable=mem_6gb,verylong,debug_verylong" .
  368. /**
  369. * Test lists for combination of IMREAD_*.
  370. */
  371. const ImreadModes all_modes_Huge_Full[] =
  372. {
  373. static_cast<ImreadModes>(IMREAD_UNCHANGED ) ,
  374. static_cast<ImreadModes>(IMREAD_GRAYSCALE ) ,
  375. static_cast<ImreadModes>(IMREAD_COLOR ) ,
  376. static_cast<ImreadModes>(IMREAD_GRAYSCALE | IMREAD_ANYDEPTH ) ,
  377. static_cast<ImreadModes>(IMREAD_GRAYSCALE | IMREAD_ANYCOLOR) ,
  378. static_cast<ImreadModes>(IMREAD_GRAYSCALE | IMREAD_ANYDEPTH | IMREAD_ANYCOLOR) ,
  379. static_cast<ImreadModes>(IMREAD_COLOR | IMREAD_ANYDEPTH ) ,
  380. static_cast<ImreadModes>(IMREAD_COLOR | IMREAD_ANYCOLOR) ,
  381. static_cast<ImreadModes>(IMREAD_COLOR | IMREAD_ANYDEPTH | IMREAD_ANYCOLOR)
  382. };
  383. const uint64_t huge_buffer_sizes_decode_Full[] =
  384. {
  385. 1048576ull, // 1 * 1024 * 1024
  386. 1073479680ull, // 1024 * 1024 * 1024 - 32768 * 4 * 2
  387. 1073741824ull, // 1024 * 1024 * 1024
  388. 2147483648ull, // 2048 * 1024 * 1024
  389. };
  390. const perf::MatType mat_types_Full[] =
  391. {
  392. CV_8UC1, // 8bit GRAY
  393. CV_8UC3, // 24bit RGB
  394. CV_8UC4, // 32bit RGBA
  395. CV_16UC1, // 16bit GRAY
  396. CV_16UC3, // 48bit RGB
  397. CV_16UC4, // 64bit RGBA
  398. };
  399. // INSTANTIATE_TEST_CASE_P(Imgcodecs_Tiff_Full, Imgcodecs_Tiff_decode_Huge,
  400. INSTANTIATE_TEST_CASE_P(DISABLED_Imgcodecs_Tiff_Full, Imgcodecs_Tiff_decode_Huge,
  401. testing::Combine(
  402. testing::ValuesIn(huge_buffer_sizes_decode_Full),
  403. testing::ValuesIn(mat_types_Full),
  404. testing::ValuesIn(all_modes_Huge_Full)
  405. )
  406. );
  407. //==================================================================================================
  408. TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian)
  409. {
  410. // see issue #2601 "16-bit Grayscale TIFF Load Failures Due to Buffer Underflow and Endianness"
  411. // Setup data for two minimal 16-bit grayscale TIFF files in both endian formats
  412. uchar tiff_sample_data[2][86] = { {
  413. // Little endian
  414. 0x49, 0x49, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xad, 0xde, 0xef, 0xbe, 0x06, 0x00, 0x00, 0x01,
  415. 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x00,
  416. 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00,
  417. 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01,
  418. 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00,
  419. 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }, {
  420. // Big endian
  421. 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x0c, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x06, 0x01, 0x00,
  422. 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00,
  423. 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10,
  424. 0x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x11,
  425. 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x17, 0x00, 0x04, 0x00, 0x00,
  426. 0x00, 0x01, 0x00, 0x00, 0x00, 0x04 }
  427. };
  428. // Test imread() for both a little endian TIFF and big endian TIFF
  429. for (int i = 0; i < 2; i++)
  430. {
  431. string filename = cv::tempfile(".tiff");
  432. // Write sample TIFF file
  433. FILE* fp = fopen(filename.c_str(), "wb");
  434. ASSERT_TRUE(fp != NULL);
  435. ASSERT_EQ((size_t)1, fwrite(tiff_sample_data[i], 86, 1, fp));
  436. fclose(fp);
  437. Mat img = imread(filename, IMREAD_UNCHANGED);
  438. EXPECT_EQ(1, img.rows);
  439. EXPECT_EQ(2, img.cols);
  440. EXPECT_EQ(CV_16U, img.type());
  441. EXPECT_EQ(sizeof(ushort), img.elemSize());
  442. EXPECT_EQ(1, img.channels());
  443. EXPECT_EQ(0xDEAD, img.at<ushort>(0,0));
  444. EXPECT_EQ(0xBEEF, img.at<ushort>(0,1));
  445. EXPECT_EQ(0, remove(filename.c_str()));
  446. }
  447. }
  448. TEST(Imgcodecs_Tiff, decode_tile_remainder)
  449. {
  450. /* see issue #3472 - dealing with tiled images where the tile size is
  451. * not a multiple of image size.
  452. * The tiled images were created with 'convert' from ImageMagick,
  453. * using the command 'convert <input> -define tiff:tile-geometry=128x128 -depth [8|16] <output>
  454. * Note that the conversion to 16 bits expands the range from 0-255 to 0-255*255,
  455. * so the test converts back but rounding errors cause small differences.
  456. */
  457. const string root = cvtest::TS::ptr()->get_data_path();
  458. cv::Mat img = imread(root + "readwrite/non_tiled.tif",-1);
  459. ASSERT_FALSE(img.empty());
  460. ASSERT_TRUE(img.channels() == 3);
  461. cv::Mat tiled8 = imread(root + "readwrite/tiled_8.tif", -1);
  462. ASSERT_FALSE(tiled8.empty());
  463. ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, tiled8);
  464. cv::Mat tiled16 = imread(root + "readwrite/tiled_16.tif", -1);
  465. ASSERT_FALSE(tiled16.empty());
  466. ASSERT_TRUE(tiled16.elemSize() == 6);
  467. tiled16.convertTo(tiled8, CV_8UC3, 1./256.);
  468. ASSERT_PRED_FORMAT2(cvtest::MatComparator(2, 0), img, tiled8);
  469. // What about 32, 64 bit?
  470. }
  471. TEST(Imgcodecs_Tiff, decode_10_12_14)
  472. {
  473. /* see issue #21700
  474. */
  475. const string root = cvtest::TS::ptr()->get_data_path();
  476. const double maxDiff = 256;//samples do not have the exact same values because of the tool that created them
  477. cv::Mat tmp;
  478. double diff = 0;
  479. cv::Mat img8UC1 = imread(root + "readwrite/pattern_8uc1.tif", cv::IMREAD_UNCHANGED);
  480. ASSERT_FALSE(img8UC1.empty());
  481. ASSERT_EQ(img8UC1.type(), CV_8UC1);
  482. cv::Mat img8UC3 = imread(root + "readwrite/pattern_8uc3.tif", cv::IMREAD_UNCHANGED);
  483. ASSERT_FALSE(img8UC3.empty());
  484. ASSERT_EQ(img8UC3.type(), CV_8UC3);
  485. cv::Mat img8UC4 = imread(root + "readwrite/pattern_8uc4.tif", cv::IMREAD_UNCHANGED);
  486. ASSERT_FALSE(img8UC4.empty());
  487. ASSERT_EQ(img8UC4.type(), CV_8UC4);
  488. cv::Mat img16UC1 = imread(root + "readwrite/pattern_16uc1.tif", cv::IMREAD_UNCHANGED);
  489. ASSERT_FALSE(img16UC1.empty());
  490. ASSERT_EQ(img16UC1.type(), CV_16UC1);
  491. ASSERT_EQ(img8UC1.size(), img16UC1.size());
  492. img8UC1.convertTo(tmp, img16UC1.type(), (1U<<(16-8)));
  493. diff = cv::norm(tmp.reshape(1), img16UC1.reshape(1), cv::NORM_INF);
  494. ASSERT_LE(diff, maxDiff);
  495. cv::Mat img16UC3 = imread(root + "readwrite/pattern_16uc3.tif", cv::IMREAD_UNCHANGED);
  496. ASSERT_FALSE(img16UC3.empty());
  497. ASSERT_EQ(img16UC3.type(), CV_16UC3);
  498. ASSERT_EQ(img8UC3.size(), img16UC3.size());
  499. img8UC3.convertTo(tmp, img16UC3.type(), (1U<<(16-8)));
  500. diff = cv::norm(tmp.reshape(1), img16UC3.reshape(1), cv::NORM_INF);
  501. ASSERT_LE(diff, maxDiff);
  502. cv::Mat img16UC4 = imread(root + "readwrite/pattern_16uc4.tif", cv::IMREAD_UNCHANGED);
  503. ASSERT_FALSE(img16UC4.empty());
  504. ASSERT_EQ(img16UC4.type(), CV_16UC4);
  505. ASSERT_EQ(img8UC4.size(), img16UC4.size());
  506. img8UC4.convertTo(tmp, img16UC4.type(), (1U<<(16-8)));
  507. diff = cv::norm(tmp.reshape(1), img16UC4.reshape(1), cv::NORM_INF);
  508. ASSERT_LE(diff, maxDiff);
  509. cv::Mat img10UC1 = imread(root + "readwrite/pattern_10uc1.tif", cv::IMREAD_UNCHANGED);
  510. ASSERT_FALSE(img10UC1.empty());
  511. ASSERT_EQ(img10UC1.type(), CV_16UC1);
  512. ASSERT_EQ(img10UC1.size(), img16UC1.size());
  513. diff = cv::norm(img10UC1.reshape(1), img16UC1.reshape(1), cv::NORM_INF);
  514. ASSERT_LE(diff, maxDiff);
  515. cv::Mat img10UC3 = imread(root + "readwrite/pattern_10uc3.tif", cv::IMREAD_UNCHANGED);
  516. ASSERT_FALSE(img10UC3.empty());
  517. ASSERT_EQ(img10UC3.type(), CV_16UC3);
  518. ASSERT_EQ(img10UC3.size(), img16UC3.size());
  519. diff = cv::norm(img10UC3.reshape(1), img16UC3.reshape(1), cv::NORM_INF);
  520. ASSERT_LE(diff, maxDiff);
  521. cv::Mat img10UC4 = imread(root + "readwrite/pattern_10uc4.tif", cv::IMREAD_UNCHANGED);
  522. ASSERT_FALSE(img10UC4.empty());
  523. ASSERT_EQ(img10UC4.type(), CV_16UC4);
  524. ASSERT_EQ(img10UC4.size(), img16UC4.size());
  525. diff = cv::norm(img10UC4.reshape(1), img16UC4.reshape(1), cv::NORM_INF);
  526. ASSERT_LE(diff, maxDiff);
  527. cv::Mat img12UC1 = imread(root + "readwrite/pattern_12uc1.tif", cv::IMREAD_UNCHANGED);
  528. ASSERT_FALSE(img12UC1.empty());
  529. ASSERT_EQ(img12UC1.type(), CV_16UC1);
  530. ASSERT_EQ(img12UC1.size(), img16UC1.size());
  531. diff = cv::norm(img12UC1.reshape(1), img16UC1.reshape(1), cv::NORM_INF);
  532. ASSERT_LE(diff, maxDiff);
  533. cv::Mat img12UC3 = imread(root + "readwrite/pattern_12uc3.tif", cv::IMREAD_UNCHANGED);
  534. ASSERT_FALSE(img12UC3.empty());
  535. ASSERT_EQ(img12UC3.type(), CV_16UC3);
  536. ASSERT_EQ(img12UC3.size(), img16UC3.size());
  537. diff = cv::norm(img12UC3.reshape(1), img16UC3.reshape(1), cv::NORM_INF);
  538. ASSERT_LE(diff, maxDiff);
  539. cv::Mat img12UC4 = imread(root + "readwrite/pattern_12uc4.tif", cv::IMREAD_UNCHANGED);
  540. ASSERT_FALSE(img12UC4.empty());
  541. ASSERT_EQ(img12UC4.type(), CV_16UC4);
  542. ASSERT_EQ(img12UC4.size(), img16UC4.size());
  543. diff = cv::norm(img12UC4.reshape(1), img16UC4.reshape(1), cv::NORM_INF);
  544. ASSERT_LE(diff, maxDiff);
  545. cv::Mat img14UC1 = imread(root + "readwrite/pattern_14uc1.tif", cv::IMREAD_UNCHANGED);
  546. ASSERT_FALSE(img14UC1.empty());
  547. ASSERT_EQ(img14UC1.type(), CV_16UC1);
  548. ASSERT_EQ(img14UC1.size(), img16UC1.size());
  549. diff = cv::norm(img14UC1.reshape(1), img16UC1.reshape(1), cv::NORM_INF);
  550. ASSERT_LE(diff, maxDiff);
  551. cv::Mat img14UC3 = imread(root + "readwrite/pattern_14uc3.tif", cv::IMREAD_UNCHANGED);
  552. ASSERT_FALSE(img14UC3.empty());
  553. ASSERT_EQ(img14UC3.type(), CV_16UC3);
  554. ASSERT_EQ(img14UC3.size(), img16UC3.size());
  555. diff = cv::norm(img14UC3.reshape(1), img16UC3.reshape(1), cv::NORM_INF);
  556. ASSERT_LE(diff, maxDiff);
  557. cv::Mat img14UC4 = imread(root + "readwrite/pattern_14uc4.tif", cv::IMREAD_UNCHANGED);
  558. ASSERT_FALSE(img14UC4.empty());
  559. ASSERT_EQ(img14UC4.type(), CV_16UC4);
  560. ASSERT_EQ(img14UC4.size(), img16UC4.size());
  561. diff = cv::norm(img14UC4.reshape(1), img16UC4.reshape(1), cv::NORM_INF);
  562. ASSERT_LE(diff, maxDiff);
  563. }
  564. TEST(Imgcodecs_Tiff, decode_infinite_rowsperstrip)
  565. {
  566. const uchar sample_data[142] = {
  567. 0x49, 0x49, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x56, 0x54,
  568. 0x56, 0x5a, 0x59, 0x55, 0x5a, 0x00, 0x0a, 0x00, 0x00, 0x01,
  569. 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  570. 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00,
  571. 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
  572. 0x08, 0x00, 0x00, 0x00, 0x03, 0x01, 0x03, 0x00, 0x01, 0x00,
  573. 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00,
  574. 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01,
  575. 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
  576. 0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
  577. 0x00, 0x00, 0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
  578. 0xff, 0xff, 0xff, 0xff, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00,
  579. 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x03, 0x00,
  580. 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
  581. 0x00, 0x00
  582. };
  583. const string filename = cv::tempfile(".tiff");
  584. std::ofstream outfile(filename.c_str(), std::ofstream::binary);
  585. outfile.write(reinterpret_cast<const char *>(sample_data), sizeof sample_data);
  586. outfile.close();
  587. EXPECT_NO_THROW(cv::imread(filename, IMREAD_UNCHANGED));
  588. EXPECT_EQ(0, remove(filename.c_str()));
  589. }
  590. TEST(Imgcodecs_Tiff, readWrite_unsigned)
  591. {
  592. const string root = cvtest::TS::ptr()->get_data_path();
  593. const string filenameInput = root + "readwrite/gray_8u.tif";
  594. const string filenameOutput = cv::tempfile(".tiff");
  595. Mat img;
  596. ASSERT_NO_THROW(img = cv::imread(filenameInput, IMREAD_UNCHANGED));
  597. ASSERT_FALSE(img.empty());
  598. ASSERT_EQ(CV_8UC1, img.type());
  599. Mat matS8;
  600. img.convertTo(matS8, CV_8SC1);
  601. bool ret_imwrite = false;
  602. ASSERT_NO_THROW(ret_imwrite = cv::imwrite(filenameOutput, matS8));
  603. ASSERT_TRUE(ret_imwrite);
  604. Mat img2;
  605. ASSERT_NO_THROW(img2 = cv::imread(filenameOutput, IMREAD_UNCHANGED));
  606. ASSERT_FALSE(img2.empty());
  607. ASSERT_EQ(img2.type(), matS8.type());
  608. ASSERT_EQ(img2.size(), matS8.size());
  609. EXPECT_LE(cvtest::norm(matS8, img2, NORM_INF | NORM_RELATIVE), 1e-3);
  610. EXPECT_EQ(0, remove(filenameOutput.c_str()));
  611. }
  612. TEST(Imgcodecs_Tiff, readWrite_32FC1)
  613. {
  614. const string root = cvtest::TS::ptr()->get_data_path();
  615. const string filenameInput = root + "readwrite/test32FC1.tiff";
  616. const string filenameOutput = cv::tempfile(".tiff");
  617. Mat img;
  618. ASSERT_NO_THROW(img = cv::imread(filenameInput, IMREAD_UNCHANGED));
  619. ASSERT_FALSE(img.empty());
  620. ASSERT_EQ(CV_32FC1,img.type());
  621. bool ret_imwrite = false;
  622. ASSERT_NO_THROW(ret_imwrite = cv::imwrite(filenameOutput, img));
  623. ASSERT_TRUE(ret_imwrite);
  624. Mat img2;
  625. ASSERT_NO_THROW(img2 = cv::imread(filenameOutput, IMREAD_UNCHANGED));
  626. ASSERT_FALSE(img2.empty());
  627. ASSERT_EQ(img2.type(), img.type());
  628. ASSERT_EQ(img2.size(), img.size());
  629. EXPECT_LE(cvtest::norm(img, img2, NORM_INF | NORM_RELATIVE), 1e-3);
  630. EXPECT_EQ(0, remove(filenameOutput.c_str()));
  631. }
  632. TEST(Imgcodecs_Tiff, readWrite_64FC1)
  633. {
  634. const string root = cvtest::TS::ptr()->get_data_path();
  635. const string filenameInput = root + "readwrite/test64FC1.tiff";
  636. const string filenameOutput = cv::tempfile(".tiff");
  637. Mat img;
  638. ASSERT_NO_THROW(img = cv::imread(filenameInput, IMREAD_UNCHANGED));
  639. ASSERT_FALSE(img.empty());
  640. ASSERT_EQ(CV_64FC1, img.type());
  641. bool ret_imwrite = false;
  642. ASSERT_NO_THROW(ret_imwrite = cv::imwrite(filenameOutput, img));
  643. ASSERT_TRUE(ret_imwrite);
  644. Mat img2;
  645. ASSERT_NO_THROW(img2 = cv::imread(filenameOutput, IMREAD_UNCHANGED));
  646. ASSERT_FALSE(img2.empty());
  647. ASSERT_EQ(img2.type(), img.type());
  648. ASSERT_EQ(img2.size(), img.size());
  649. EXPECT_LE(cvtest::norm(img, img2, NORM_INF | NORM_RELATIVE), 1e-3);
  650. EXPECT_EQ(0, remove(filenameOutput.c_str()));
  651. }
  652. TEST(Imgcodecs_Tiff, readWrite_32FC3_SGILOG)
  653. {
  654. const string root = cvtest::TS::ptr()->get_data_path();
  655. const string filenameInput = root + "readwrite/test32FC3_sgilog.tiff";
  656. const string filenameOutput = cv::tempfile(".tiff");
  657. Mat img;
  658. ASSERT_NO_THROW(img = cv::imread(filenameInput, IMREAD_UNCHANGED));
  659. ASSERT_FALSE(img.empty());
  660. ASSERT_EQ(CV_32FC3, img.type());
  661. bool ret_imwrite = false;
  662. ASSERT_NO_THROW(ret_imwrite = cv::imwrite(filenameOutput, img));
  663. ASSERT_TRUE(ret_imwrite);
  664. Mat img2;
  665. ASSERT_NO_THROW(img2 = cv::imread(filenameOutput, IMREAD_UNCHANGED));
  666. ASSERT_FALSE(img2.empty());
  667. ASSERT_EQ(img2.type(), img.type());
  668. ASSERT_EQ(img2.size(), img.size());
  669. EXPECT_LE(cvtest::norm(img, img2, NORM_INF | NORM_RELATIVE), 0.01);
  670. EXPECT_EQ(0, remove(filenameOutput.c_str()));
  671. }
  672. TEST(Imgcodecs_Tiff, readWrite_32FC3_RAW)
  673. {
  674. const string root = cvtest::TS::ptr()->get_data_path();
  675. const string filenameInput = root + "readwrite/test32FC3_raw.tiff";
  676. const string filenameOutput = cv::tempfile(".tiff");
  677. Mat img;
  678. ASSERT_NO_THROW(img = cv::imread(filenameInput, IMREAD_UNCHANGED));
  679. ASSERT_FALSE(img.empty());
  680. ASSERT_EQ(CV_32FC3, img.type());
  681. std::vector<int> params;
  682. params.push_back(IMWRITE_TIFF_COMPRESSION);
  683. params.push_back(IMWRITE_TIFF_COMPRESSION_NONE);
  684. bool ret_imwrite = false;
  685. ASSERT_NO_THROW(ret_imwrite = cv::imwrite(filenameOutput, img, params));
  686. ASSERT_TRUE(ret_imwrite);
  687. Mat img2;
  688. ASSERT_NO_THROW(img2 = cv::imread(filenameOutput, IMREAD_UNCHANGED));
  689. ASSERT_FALSE(img2.empty());
  690. ASSERT_EQ(img2.type(), img.type());
  691. ASSERT_EQ(img2.size(), img.size());
  692. EXPECT_LE(cvtest::norm(img, img2, NORM_INF | NORM_RELATIVE), 1e-3);
  693. EXPECT_EQ(0, remove(filenameOutput.c_str()));
  694. }
  695. TEST(Imgcodecs_Tiff, read_palette_color_image)
  696. {
  697. const string root = cvtest::TS::ptr()->get_data_path();
  698. const string filenameInput = root + "readwrite/test_palette_color_image.tif";
  699. Mat img;
  700. ASSERT_NO_THROW(img = cv::imread(filenameInput, IMREAD_UNCHANGED));
  701. ASSERT_FALSE(img.empty());
  702. ASSERT_EQ(CV_8UC3, img.type());
  703. }
  704. TEST(Imgcodecs_Tiff, read_palette_color_image_rgb_and_bgr)
  705. {
  706. const string root = cvtest::TS::ptr()->get_data_path();
  707. const string filenameInput = root + "readwrite/test_palette_color_image.tif";
  708. Mat img_rgb, img_bgr;
  709. ASSERT_NO_THROW(img_rgb = cv::imread(filenameInput, IMREAD_COLOR_RGB));
  710. ASSERT_NO_THROW(img_bgr = cv::imread(filenameInput, IMREAD_COLOR_BGR));
  711. ASSERT_FALSE(img_rgb.empty());
  712. ASSERT_EQ(CV_8UC3, img_rgb.type());
  713. ASSERT_FALSE(img_bgr.empty());
  714. ASSERT_EQ(CV_8UC3, img_bgr.type());
  715. EXPECT_EQ(img_rgb.at<Vec3b>(32, 24), Vec3b(255, 0, 0));
  716. EXPECT_EQ(img_bgr.at<Vec3b>(32, 24), Vec3b(0, 0, 255));
  717. }
  718. TEST(Imgcodecs_Tiff, read_4_bit_palette_color_image)
  719. {
  720. const string root = cvtest::TS::ptr()->get_data_path();
  721. const string filenameInput = root + "readwrite/4-bit_palette_color.tif";
  722. Mat img;
  723. ASSERT_NO_THROW(img = cv::imread(filenameInput, IMREAD_UNCHANGED));
  724. ASSERT_FALSE(img.empty());
  725. ASSERT_EQ(CV_8UC3, img.type());
  726. }
  727. TEST(Imgcodecs_Tiff, readWrite_predictor)
  728. {
  729. /* see issue #21871
  730. */
  731. const uchar sample_data[160] = {
  732. 0xff, 0xff, 0xff, 0xff, 0x88, 0x88, 0xff, 0xff, 0x88, 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0x88,
  733. 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
  734. 0xff, 0x00, 0x00, 0x44, 0xff, 0xff, 0x88, 0xff, 0x33, 0x00, 0x66, 0xff, 0xff, 0x88, 0x00, 0x44,
  735. 0x88, 0x00, 0x44, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x44, 0xff, 0xff, 0x11, 0x00, 0xff,
  736. 0x11, 0x00, 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
  737. 0x11, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x00, 0x88, 0xff, 0x00, 0x66, 0xff,
  738. 0x11, 0x00, 0x66, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x44, 0x33, 0x00, 0xff, 0xff,
  739. 0x88, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
  740. 0xff, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x33, 0x00, 0x00, 0x66, 0xff, 0xff,
  741. 0xff, 0xff, 0x88, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff
  742. };
  743. cv::Mat mat(10, 16, CV_8UC1, (void*)sample_data);
  744. int methods[] = {
  745. IMWRITE_TIFF_COMPRESSION_NONE, IMWRITE_TIFF_COMPRESSION_LZW,
  746. IMWRITE_TIFF_COMPRESSION_PACKBITS, IMWRITE_TIFF_COMPRESSION_DEFLATE,
  747. IMWRITE_TIFF_COMPRESSION_ADOBE_DEFLATE
  748. };
  749. for (size_t i = 0; i < sizeof(methods) / sizeof(int); i++)
  750. {
  751. string out = cv::tempfile(".tif");
  752. std::vector<int> params;
  753. params.push_back(IMWRITE_TIFF_COMPRESSION);
  754. params.push_back(methods[i]);
  755. params.push_back(IMWRITE_TIFF_PREDICTOR);
  756. params.push_back(IMWRITE_TIFF_PREDICTOR_HORIZONTAL);
  757. bool ret_imwrite = false;
  758. ASSERT_NO_THROW(ret_imwrite = cv::imwrite(out, mat, params));
  759. ASSERT_TRUE(ret_imwrite);
  760. Mat img;
  761. ASSERT_NO_THROW(img = cv::imread(out, IMREAD_UNCHANGED));
  762. ASSERT_FALSE(img.empty());
  763. ASSERT_EQ(0, cv::norm(mat, img, cv::NORM_INF));
  764. EXPECT_EQ(0, remove(out.c_str()));
  765. }
  766. }
  767. // See https://github.com/opencv/opencv/issues/23416
  768. typedef std::pair<perf::MatType,bool> Imgcodes_Tiff_TypeAndComp;
  769. typedef testing::TestWithParam< Imgcodes_Tiff_TypeAndComp > Imgcodecs_Tiff_Types;
  770. TEST_P(Imgcodecs_Tiff_Types, readWrite_alltypes)
  771. {
  772. const int mat_types = static_cast<int>(get<0>(GetParam()));
  773. const bool isCompAvailable = get<1>(GetParam());
  774. // Create a test image.
  775. const Mat src = cv::Mat::zeros( 120, 160, mat_types );
  776. {
  777. // Add noise to test compression.
  778. cv::Mat roi = cv::Mat(src, cv::Rect(0, 0, src.cols, src.rows/2));
  779. cv::randu(roi, cv::Scalar(0), cv::Scalar(256));
  780. }
  781. // Try to encode/decode the test image with LZW compression.
  782. std::vector<uchar> bufLZW;
  783. {
  784. std::vector<int> params;
  785. params.push_back(IMWRITE_TIFF_COMPRESSION);
  786. params.push_back(IMWRITE_TIFF_COMPRESSION_LZW);
  787. ASSERT_NO_THROW(cv::imencode(".tiff", src, bufLZW, params));
  788. Mat dstLZW;
  789. ASSERT_NO_THROW(cv::imdecode( bufLZW, IMREAD_UNCHANGED, &dstLZW));
  790. ASSERT_EQ(dstLZW.type(), src.type());
  791. ASSERT_EQ(dstLZW.size(), src.size());
  792. ASSERT_LE(cvtest::norm(dstLZW, src, NORM_INF | NORM_RELATIVE), 1e-3);
  793. }
  794. // Try to encode/decode the test image with RAW.
  795. std::vector<uchar> bufRAW;
  796. {
  797. std::vector<int> params;
  798. params.push_back(IMWRITE_TIFF_COMPRESSION);
  799. params.push_back(IMWRITE_TIFF_COMPRESSION_NONE);
  800. ASSERT_NO_THROW(cv::imencode(".tiff", src, bufRAW, params));
  801. Mat dstRAW;
  802. ASSERT_NO_THROW(cv::imdecode( bufRAW, IMREAD_UNCHANGED, &dstRAW));
  803. ASSERT_EQ(dstRAW.type(), src.type());
  804. ASSERT_EQ(dstRAW.size(), src.size());
  805. ASSERT_LE(cvtest::norm(dstRAW, src, NORM_INF | NORM_RELATIVE), 1e-3);
  806. }
  807. // Compare LZW and RAW streams.
  808. EXPECT_EQ(bufLZW == bufRAW, !isCompAvailable);
  809. }
  810. Imgcodes_Tiff_TypeAndComp all_types[] = {
  811. { CV_8UC1, true }, { CV_8UC3, true }, { CV_8UC4, true },
  812. { CV_8SC1, true }, { CV_8SC3, true }, { CV_8SC4, true },
  813. { CV_16UC1, true }, { CV_16UC3, true }, { CV_16UC4, true },
  814. { CV_16SC1, true }, { CV_16SC3, true }, { CV_16SC4, true },
  815. { CV_32SC1, true }, { CV_32SC3, true }, { CV_32SC4, true },
  816. { CV_32FC1, false }, { CV_32FC3, false }, { CV_32FC4, false }, // No compression
  817. { CV_64FC1, false }, { CV_64FC3, false }, { CV_64FC4, false } // No compression
  818. };
  819. INSTANTIATE_TEST_CASE_P(AllTypes, Imgcodecs_Tiff_Types, testing::ValuesIn(all_types));
  820. //==================================================================================================
  821. typedef testing::TestWithParam<int> Imgcodecs_Tiff_Modes;
  822. TEST_P(Imgcodecs_Tiff_Modes, decode_multipage)
  823. {
  824. const int mode = GetParam();
  825. const string root = cvtest::TS::ptr()->get_data_path();
  826. const string filename = root + "readwrite/multipage.tif";
  827. const string page_files[] = {
  828. "readwrite/multipage_p1.tif",
  829. "readwrite/multipage_p2.tif",
  830. "readwrite/multipage_p3.tif",
  831. "readwrite/multipage_p4.tif",
  832. "readwrite/multipage_p5.tif",
  833. "readwrite/multipage_p6.tif"
  834. };
  835. const size_t page_count = sizeof(page_files)/sizeof(page_files[0]);
  836. vector<Mat> pages;
  837. bool res = imreadmulti(filename, pages, mode);
  838. ASSERT_TRUE(res == true);
  839. ASSERT_EQ(page_count, pages.size());
  840. for (size_t i = 0; i < page_count; i++)
  841. {
  842. const Mat page = imread(root + page_files[i], mode);
  843. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), page, pages[i]);
  844. }
  845. }
  846. TEST_P(Imgcodecs_Tiff_Modes, decode_multipage_use_memory_buffer_all_pages)
  847. {
  848. const int mode = GetParam();
  849. const string root = cvtest::TS::ptr()->get_data_path();
  850. const string filename = root + "readwrite/multipage.tif";
  851. const string page_files[] = {
  852. "readwrite/multipage_p1.tif",
  853. "readwrite/multipage_p2.tif",
  854. "readwrite/multipage_p3.tif",
  855. "readwrite/multipage_p4.tif",
  856. "readwrite/multipage_p5.tif",
  857. "readwrite/multipage_p6.tif"
  858. };
  859. const size_t page_count = sizeof(page_files) / sizeof(page_files[0]);
  860. vector<Mat> pages;
  861. FILE* fp = fopen(filename.c_str(), "rb");
  862. ASSERT_TRUE(fp != NULL);
  863. fseek(fp, 0, SEEK_END);
  864. const size_t file_size = ftell(fp);
  865. fseek(fp, 0, SEEK_SET);
  866. std::vector<uchar> buf(file_size);
  867. const size_t actual_read = fread(&buf[0], 1, file_size, fp);
  868. fclose(fp);
  869. ASSERT_EQ(file_size, actual_read);
  870. ASSERT_EQ(file_size, static_cast<size_t>(buf.size()));
  871. bool res = imdecodemulti(buf, mode, pages);
  872. ASSERT_TRUE(res == true);
  873. ASSERT_EQ(page_count, pages.size());
  874. for (size_t i = 0; i < page_count; i++)
  875. {
  876. const Mat page = imread(root + page_files[i], mode);
  877. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), page, pages[i]);
  878. }
  879. }
  880. TEST_P(Imgcodecs_Tiff_Modes, decode_multipage_use_memory_buffer_selected_pages)
  881. {
  882. const int mode = GetParam();
  883. const string root = cvtest::TS::ptr()->get_data_path();
  884. const string filename = root + "readwrite/multipage.tif";
  885. const string page_files[] = {
  886. "readwrite/multipage_p1.tif",
  887. "readwrite/multipage_p2.tif",
  888. "readwrite/multipage_p3.tif",
  889. "readwrite/multipage_p4.tif",
  890. "readwrite/multipage_p5.tif",
  891. "readwrite/multipage_p6.tif"
  892. };
  893. const size_t page_count = sizeof(page_files) / sizeof(page_files[0]);
  894. FILE* fp = fopen(filename.c_str(), "rb");
  895. ASSERT_TRUE(fp != NULL);
  896. fseek(fp, 0, SEEK_END);
  897. const size_t file_size = ftell(fp);
  898. fseek(fp, 0, SEEK_SET);
  899. std::vector<uchar> buf(file_size);
  900. const size_t actual_read = fread(&buf[0], 1, file_size, fp);
  901. fclose(fp);
  902. ASSERT_EQ(file_size, actual_read);
  903. ASSERT_EQ(file_size, static_cast<size_t>(buf.size()));
  904. const Range range(1, page_count - 1);
  905. ASSERT_GE(range.size(), 1);
  906. vector<Mat> middle_pages_from_imread;
  907. for (int page_i = range.start; page_i < range.end; page_i++)
  908. {
  909. const Mat page = imread(root + page_files[page_i], mode);
  910. middle_pages_from_imread.push_back(page);
  911. }
  912. ASSERT_EQ(
  913. static_cast<size_t>(range.size()),
  914. static_cast<size_t>(middle_pages_from_imread.size())
  915. );
  916. vector<Mat> middle_pages_from_imdecodemulti;
  917. const bool res = imdecodemulti(buf, mode, middle_pages_from_imdecodemulti, range);
  918. ASSERT_TRUE(res == true);
  919. EXPECT_EQ(middle_pages_from_imread.size(), middle_pages_from_imdecodemulti.size());
  920. for (int i = 0, e = range.size(); i < e; i++)
  921. {
  922. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0),
  923. middle_pages_from_imread[i],
  924. middle_pages_from_imdecodemulti[i]);
  925. }
  926. }
  927. const int all_modes[] =
  928. {
  929. IMREAD_UNCHANGED,
  930. IMREAD_GRAYSCALE,
  931. IMREAD_COLOR,
  932. IMREAD_COLOR_RGB,
  933. IMREAD_ANYDEPTH,
  934. IMREAD_ANYCOLOR
  935. };
  936. INSTANTIATE_TEST_CASE_P(AllModes, Imgcodecs_Tiff_Modes, testing::ValuesIn(all_modes));
  937. //==================================================================================================
  938. TEST(Imgcodecs_Tiff_Modes, write_multipage)
  939. {
  940. const string root = cvtest::TS::ptr()->get_data_path();
  941. const string page_files[] = {
  942. "readwrite/multipage_p1.tif",
  943. "readwrite/multipage_p2.tif",
  944. "readwrite/multipage_p3.tif",
  945. "readwrite/multipage_p4.tif",
  946. "readwrite/multipage_p5.tif",
  947. "readwrite/multipage_p6.tif"
  948. };
  949. const size_t page_count = sizeof(page_files) / sizeof(page_files[0]);
  950. vector<Mat> pages;
  951. for (size_t i = 0; i < page_count; i++)
  952. {
  953. const Mat page = imread(root + page_files[i], IMREAD_REDUCED_GRAYSCALE_8 + (int)i);
  954. pages.push_back(page);
  955. }
  956. string tmp_filename = cv::tempfile(".tiff");
  957. bool res = imwrite(tmp_filename, pages);
  958. ASSERT_TRUE(res);
  959. vector<Mat> read_pages;
  960. imreadmulti(tmp_filename, read_pages);
  961. for (size_t i = 0; i < page_count; i++)
  962. {
  963. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), read_pages[i], pages[i]);
  964. }
  965. EXPECT_EQ(0, remove(tmp_filename.c_str()));
  966. }
  967. //==================================================================================================
  968. TEST(Imgcodecs_Tiff, imdecode_no_exception_temporary_file_removed)
  969. {
  970. const string root = cvtest::TS::ptr()->get_data_path();
  971. const string filename = root + "../cv/shared/lena.png";
  972. cv::Mat img = cv::imread(filename);
  973. ASSERT_FALSE(img.empty());
  974. std::vector<uchar> buf;
  975. EXPECT_NO_THROW(cv::imencode(".tiff", img, buf));
  976. EXPECT_NO_THROW(cv::imdecode(buf, IMREAD_UNCHANGED));
  977. }
  978. TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr12989_grayscale)
  979. {
  980. const string filename = cvtest::findDataFile("readwrite/bitsperpixel1.tiff");
  981. cv::Mat img;
  982. ASSERT_NO_THROW(img = cv::imread(filename, IMREAD_GRAYSCALE));
  983. ASSERT_FALSE(img.empty());
  984. EXPECT_EQ(64, img.cols);
  985. EXPECT_EQ(64, img.rows);
  986. EXPECT_EQ(CV_8UC1, img.type()) << cv::typeToString(img.type());
  987. // Check for 0/255 values only: 267 + 3829 = 64*64
  988. EXPECT_EQ(267, countNonZero(img == 0));
  989. EXPECT_EQ(3829, countNonZero(img == 255));
  990. }
  991. TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr12989_default)
  992. {
  993. const string filename = cvtest::findDataFile("readwrite/bitsperpixel1.tiff");
  994. cv::Mat img;
  995. ASSERT_NO_THROW(img = cv::imread(filename)); // by default image type is CV_8UC3
  996. ASSERT_FALSE(img.empty());
  997. EXPECT_EQ(64, img.cols);
  998. EXPECT_EQ(64, img.rows);
  999. EXPECT_EQ(CV_8UC3, img.type()) << cv::typeToString(img.type());
  1000. }
  1001. TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr17275_grayscale)
  1002. {
  1003. const string filename = cvtest::findDataFile("readwrite/bitsperpixel1_min.tiff");
  1004. cv::Mat img;
  1005. ASSERT_NO_THROW(img = cv::imread(filename, IMREAD_GRAYSCALE));
  1006. ASSERT_FALSE(img.empty());
  1007. EXPECT_EQ(64, img.cols);
  1008. EXPECT_EQ(64, img.rows);
  1009. EXPECT_EQ(CV_8UC1, img.type()) << cv::typeToString(img.type());
  1010. // Check for 0/255 values only: 267 + 3829 = 64*64
  1011. EXPECT_EQ(267, countNonZero(img == 0));
  1012. EXPECT_EQ(3829, countNonZero(img == 255));
  1013. }
  1014. TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr17275_default)
  1015. {
  1016. const string filename = cvtest::findDataFile("readwrite/bitsperpixel1_min.tiff");
  1017. cv::Mat img;
  1018. ASSERT_NO_THROW(img = cv::imread(filename)); // by default image type is CV_8UC3
  1019. ASSERT_FALSE(img.empty());
  1020. EXPECT_EQ(64, img.cols);
  1021. EXPECT_EQ(64, img.rows);
  1022. EXPECT_EQ(CV_8UC3, img.type()) << cv::typeToString(img.type());
  1023. }
  1024. TEST(Imgcodecs_Tiff, count_multipage)
  1025. {
  1026. const string root = cvtest::TS::ptr()->get_data_path();
  1027. {
  1028. const string filename = root + "readwrite/multipage.tif";
  1029. ASSERT_EQ((size_t)6, imcount(filename));
  1030. }
  1031. {
  1032. const string filename = root + "readwrite/test32FC3_raw.tiff";
  1033. ASSERT_EQ((size_t)1, imcount(filename));
  1034. }
  1035. }
  1036. TEST(Imgcodecs_Tiff, read_multipage_indexed)
  1037. {
  1038. const string root = cvtest::TS::ptr()->get_data_path();
  1039. const string filename = root + "readwrite/multipage.tif";
  1040. const string page_files[] = {
  1041. "readwrite/multipage_p1.tif",
  1042. "readwrite/multipage_p2.tif",
  1043. "readwrite/multipage_p3.tif",
  1044. "readwrite/multipage_p4.tif",
  1045. "readwrite/multipage_p5.tif",
  1046. "readwrite/multipage_p6.tif"
  1047. };
  1048. const int page_count = sizeof(page_files) / sizeof(page_files[0]);
  1049. vector<Mat> single_pages;
  1050. for (int i = 0; i < page_count; i++)
  1051. {
  1052. // imread and imreadmulti have different default values for the flag
  1053. const Mat page = imread(root + page_files[i], IMREAD_ANYCOLOR);
  1054. single_pages.push_back(page);
  1055. }
  1056. ASSERT_EQ((size_t)page_count, single_pages.size());
  1057. {
  1058. SCOPED_TRACE("Edge Cases");
  1059. vector<Mat> multi_pages;
  1060. bool res = imreadmulti(filename, multi_pages, 0, 0);
  1061. // If we asked for 0 images and we successfully read 0 images should this be false ?
  1062. ASSERT_TRUE(res == false);
  1063. ASSERT_EQ((size_t)0, multi_pages.size());
  1064. res = imreadmulti(filename, multi_pages, 0, 123123);
  1065. ASSERT_TRUE(res == true);
  1066. ASSERT_EQ((size_t)6, multi_pages.size());
  1067. }
  1068. {
  1069. SCOPED_TRACE("Read all with indices");
  1070. vector<Mat> multi_pages;
  1071. bool res = imreadmulti(filename, multi_pages, 0, 6);
  1072. ASSERT_TRUE(res == true);
  1073. ASSERT_EQ((size_t)page_count, multi_pages.size());
  1074. for (int i = 0; i < page_count; i++)
  1075. {
  1076. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), multi_pages[i], single_pages[i]);
  1077. }
  1078. }
  1079. {
  1080. SCOPED_TRACE("Read one by one");
  1081. vector<Mat> multi_pages;
  1082. for (int i = 0; i < page_count; i++)
  1083. {
  1084. bool res = imreadmulti(filename, multi_pages, i, 1);
  1085. ASSERT_TRUE(res == true);
  1086. ASSERT_EQ((size_t)1, multi_pages.size());
  1087. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), multi_pages[0], single_pages[i]);
  1088. multi_pages.clear();
  1089. }
  1090. }
  1091. {
  1092. SCOPED_TRACE("Read multiple at a time");
  1093. vector<Mat> multi_pages;
  1094. for (int i = 0; i < page_count/2; i++)
  1095. {
  1096. bool res = imreadmulti(filename, multi_pages, i*2, 2);
  1097. ASSERT_TRUE(res == true);
  1098. ASSERT_EQ((size_t)2, multi_pages.size());
  1099. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), multi_pages[0], single_pages[i * 2]) << i;
  1100. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), multi_pages[1], single_pages[i * 2 + 1]);
  1101. multi_pages.clear();
  1102. }
  1103. }
  1104. }
  1105. TEST(Imgcodecs_Tiff, read_bigtiff_images)
  1106. {
  1107. const string root = cvtest::TS::ptr()->get_data_path();
  1108. const string filenamesInput[] = {
  1109. "readwrite/BigTIFF.tif",
  1110. "readwrite/BigTIFFMotorola.tif",
  1111. "readwrite/BigTIFFLong.tif",
  1112. "readwrite/BigTIFFLong8.tif",
  1113. "readwrite/BigTIFFMotorolaLongStrips.tif",
  1114. "readwrite/BigTIFFLong8Tiles.tif",
  1115. "readwrite/BigTIFFSubIFD4.tif",
  1116. "readwrite/BigTIFFSubIFD8.tif"
  1117. };
  1118. for (int i = 0; i < 8; i++)
  1119. {
  1120. const Mat bigtiff_img = imread(root + filenamesInput[i], IMREAD_UNCHANGED);
  1121. ASSERT_FALSE(bigtiff_img.empty());
  1122. EXPECT_EQ(64, bigtiff_img.cols);
  1123. EXPECT_EQ(64, bigtiff_img.rows);
  1124. ASSERT_EQ(CV_8UC3, bigtiff_img.type());
  1125. }
  1126. }
  1127. TEST(Imgcodecs_Tiff, read_junk) {
  1128. // Test exercises the tiff error handler integration.
  1129. // Error messages can be seen with OPENCV_LOG_LEVEL=DEBUG
  1130. const char junk[] = "II\x2a\x00\x08\x00\x00\x00\x00\x00\x00\x00";
  1131. cv::Mat junkInputArray(1, sizeof(junk) - 1, CV_8UC1, (void*)junk);
  1132. cv::Mat img;
  1133. ASSERT_NO_THROW(img = cv::imdecode(junkInputArray, IMREAD_UNCHANGED));
  1134. ASSERT_TRUE(img.empty());
  1135. }
  1136. #endif
  1137. }} // namespace