remove(file4.c_str());
}
-TEST(Highgui_Tiff, write_read_16bit_big_little_endian)
+class CV_GrfmtReadTifTiledWithNotFullTiles: public cvtest::BaseTest
{
+ // see issue #2601 "16-bit Grayscale TIFF Load Failures Due to Buffer Underflow and Endianness"
+
+ // Setup data for two minimal 16-bit grayscale TIFF files in both endian formats
+ uchar tiff_sample_data[2][86] = { {
+ // Little endian
+ 0x49, 0x49, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xad, 0xde, 0xef, 0xbe, 0x06, 0x00, 0x00, 0x01,
+ 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01,
+ 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }, {
+ // Big endian
+ 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x0c, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x06, 0x01, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10,
+ 0x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x11,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x17, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x04 }
+ };
+
+ // Test imread() for both a little endian TIFF and big endian TIFF
+ for (int i = 0; i < 2; i++)
+ {
+ string filename = cv::tempfile(".tiff");
+
+ // Write sample TIFF file
+ FILE* fp = fopen(filename.c_str(), "wb");
+ ASSERT_TRUE(fp != NULL);
+ ASSERT_EQ((size_t)1, fwrite(tiff_sample_data, 86, 1, fp));
+ fclose(fp);
+
+ Mat img = imread(filename, CV_LOAD_IMAGE_UNCHANGED);
+
+ EXPECT_EQ(1, img.rows);
+ EXPECT_EQ(2, img.cols);
+ EXPECT_EQ(CV_16U, img.type());
+ EXPECT_EQ(sizeof(ushort), img.elemSize());
+ EXPECT_EQ(1, img.channels());
+ EXPECT_EQ(0xDEAD, img.at<ushort>(0,0));
+ EXPECT_EQ(0xBEEF, img.at<ushort>(0,1));
+
+ remove(filename.c_str());
+ }
+ }
+
++class CV_GrfmtReadTifTiledWithNotFullTiles: public cvtest::BaseTest
++{
+public:
+ void run(int)
+ {
+ try
+ {
+ /* see issue #3472 - dealing with tiled images where the tile size is
+ * not a multiple of image size.
+ * The tiled images were created with 'convert' from ImageMagick,
+ * using the command 'convert <input> -define tiff:tile-geometry=128x128 -depth [8|16] <output>
+ * Note that the conversion to 16 bits expands the range from 0-255 to 0-255*255,
+ * so the test converts back but rounding errors cause small differences.
+ */
+ cv::Mat img = imread(string(ts->get_data_path()) + "readwrite/non_tiled.tif",-1);
+ if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
+ ASSERT_TRUE(img.channels() == 3);
+ cv::Mat tiled8 = imread(string(ts->get_data_path()) + "readwrite/tiled_8.tif", -1);
+ if (tiled8.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
+ ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, tiled8);
+
+ cv::Mat tiled16 = imread(string(ts->get_data_path()) + "readwrite/tiled_16.tif", -1);
+ if (tiled16.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
+ ASSERT_TRUE(tiled16.elemSize() == 6);
+ tiled16.convertTo(tiled8, CV_8UC3, 1./256.);
+ ASSERT_PRED_FORMAT2(cvtest::MatComparator(2, 0), img, tiled8);
+ // What about 32, 64 bit?
+ }
+ catch(...)
+ {
+ ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION);
+ }
+ ts->set_failed_test_info(cvtest::TS::OK);
+ }
+};
+
+TEST(Highgui_Tiff, decode_tile_remainder)
+{
+ CV_GrfmtReadTifTiledWithNotFullTiles test; test.safe_run();
+}
+
#endif