Path: blob/master/modules/imgcodecs/test/test_tiff.cpp
16354 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html3#include "test_precomp.hpp"45namespace opencv_test { namespace {67#ifdef HAVE_TIFF89// these defines are used to resolve conflict between tiff.h and opencv2/core/types_c.h10#define uint64 uint64_hack_11#define int64 int64_hack_12#include "tiff.h"1314#ifdef __ANDROID__15// Test disabled as it uses a lot of memory.16// It is killed with SIGKILL by out of memory killer.17TEST(Imgcodecs_Tiff, DISABLED_decode_tile16384x16384)18#else19TEST(Imgcodecs_Tiff, decode_tile16384x16384)20#endif21{22// see issue #216123cv::Mat big(16384, 16384, CV_8UC1, cv::Scalar::all(0));24string file3 = cv::tempfile(".tiff");25string file4 = cv::tempfile(".tiff");2627std::vector<int> params;28params.push_back(TIFFTAG_ROWSPERSTRIP);29params.push_back(big.rows);30EXPECT_NO_THROW(cv::imwrite(file4, big, params));31EXPECT_NO_THROW(cv::imwrite(file3, big.colRange(0, big.cols - 1), params));32big.release();3334try35{36cv::imread(file3, IMREAD_UNCHANGED);37EXPECT_NO_THROW(cv::imread(file4, IMREAD_UNCHANGED));38}39catch(const std::bad_alloc&)40{41// not enough memory42}4344EXPECT_EQ(0, remove(file3.c_str()));45EXPECT_EQ(0, remove(file4.c_str()));46}4748TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian)49{50// see issue #2601 "16-bit Grayscale TIFF Load Failures Due to Buffer Underflow and Endianness"5152// Setup data for two minimal 16-bit grayscale TIFF files in both endian formats53uchar tiff_sample_data[2][86] = { {54// Little endian550x49, 0x49, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xad, 0xde, 0xef, 0xbe, 0x06, 0x00, 0x00, 0x01,560x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x00,570x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00,580x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01,590x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00,600x00, 0x00, 0x04, 0x00, 0x00, 0x00 }, {61// Big endian620x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x0c, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x06, 0x01, 0x00,630x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00,640x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10,650x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x11,660x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x17, 0x00, 0x04, 0x00, 0x00,670x00, 0x01, 0x00, 0x00, 0x00, 0x04 }68};6970// Test imread() for both a little endian TIFF and big endian TIFF71for (int i = 0; i < 2; i++)72{73string filename = cv::tempfile(".tiff");7475// Write sample TIFF file76FILE* fp = fopen(filename.c_str(), "wb");77ASSERT_TRUE(fp != NULL);78ASSERT_EQ((size_t)1, fwrite(tiff_sample_data, 86, 1, fp));79fclose(fp);8081Mat img = imread(filename, IMREAD_UNCHANGED);8283EXPECT_EQ(1, img.rows);84EXPECT_EQ(2, img.cols);85EXPECT_EQ(CV_16U, img.type());86EXPECT_EQ(sizeof(ushort), img.elemSize());87EXPECT_EQ(1, img.channels());88EXPECT_EQ(0xDEAD, img.at<ushort>(0,0));89EXPECT_EQ(0xBEEF, img.at<ushort>(0,1));9091EXPECT_EQ(0, remove(filename.c_str()));92}93}9495TEST(Imgcodecs_Tiff, decode_tile_remainder)96{97/* see issue #3472 - dealing with tiled images where the tile size is98* not a multiple of image size.99* The tiled images were created with 'convert' from ImageMagick,100* using the command 'convert <input> -define tiff:tile-geometry=128x128 -depth [8|16] <output>101* Note that the conversion to 16 bits expands the range from 0-255 to 0-255*255,102* so the test converts back but rounding errors cause small differences.103*/104const string root = cvtest::TS::ptr()->get_data_path();105cv::Mat img = imread(root + "readwrite/non_tiled.tif",-1);106ASSERT_FALSE(img.empty());107ASSERT_TRUE(img.channels() == 3);108cv::Mat tiled8 = imread(root + "readwrite/tiled_8.tif", -1);109ASSERT_FALSE(tiled8.empty());110ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, tiled8);111cv::Mat tiled16 = imread(root + "readwrite/tiled_16.tif", -1);112ASSERT_FALSE(tiled16.empty());113ASSERT_TRUE(tiled16.elemSize() == 6);114tiled16.convertTo(tiled8, CV_8UC3, 1./256.);115ASSERT_PRED_FORMAT2(cvtest::MatComparator(2, 0), img, tiled8);116// What about 32, 64 bit?117}118119TEST(Imgcodecs_Tiff, decode_infinite_rowsperstrip)120{121const uchar sample_data[142] = {1220x49, 0x49, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x56, 0x54,1230x56, 0x5a, 0x59, 0x55, 0x5a, 0x00, 0x0a, 0x00, 0x00, 0x01,1240x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,1250x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00,1260x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,1270x08, 0x00, 0x00, 0x00, 0x03, 0x01, 0x03, 0x00, 0x01, 0x00,1280x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00,1290x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01,1300x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,1310x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,1320x00, 0x00, 0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,1330xff, 0xff, 0xff, 0xff, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00,1340x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x03, 0x00,1350x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,1360x00, 0x00137};138139const string filename = cv::tempfile(".tiff");140std::ofstream outfile(filename.c_str(), std::ofstream::binary);141outfile.write(reinterpret_cast<const char *>(sample_data), sizeof sample_data);142outfile.close();143144EXPECT_NO_THROW(cv::imread(filename, IMREAD_UNCHANGED));145146EXPECT_EQ(0, remove(filename.c_str()));147}148149TEST(Imgcodecs_Tiff, readWrite_32FC1)150{151const string root = cvtest::TS::ptr()->get_data_path();152const string filenameInput = root + "readwrite/test32FC1.tiff";153const string filenameOutput = cv::tempfile(".tiff");154const Mat img = cv::imread(filenameInput, IMREAD_UNCHANGED);155ASSERT_FALSE(img.empty());156ASSERT_EQ(CV_32FC1,img.type());157158ASSERT_TRUE(cv::imwrite(filenameOutput, img));159const Mat img2 = cv::imread(filenameOutput, IMREAD_UNCHANGED);160ASSERT_EQ(img2.type(),img.type());161ASSERT_EQ(img2.size(),img.size());162EXPECT_GE(1e-3, cvtest::norm(img, img2, NORM_INF | NORM_RELATIVE));163EXPECT_EQ(0, remove(filenameOutput.c_str()));164}165166//==================================================================================================167168typedef testing::TestWithParam<int> Imgcodecs_Tiff_Modes;169170TEST_P(Imgcodecs_Tiff_Modes, decode_multipage)171{172const int mode = GetParam();173const string root = cvtest::TS::ptr()->get_data_path();174const string filename = root + "readwrite/multipage.tif";175const string page_files[] = {176"readwrite/multipage_p1.tif",177"readwrite/multipage_p2.tif",178"readwrite/multipage_p3.tif",179"readwrite/multipage_p4.tif",180"readwrite/multipage_p5.tif",181"readwrite/multipage_p6.tif"182};183const size_t page_count = sizeof(page_files)/sizeof(page_files[0]);184vector<Mat> pages;185bool res = imreadmulti(filename, pages, mode);186ASSERT_TRUE(res == true);187ASSERT_EQ(page_count, pages.size());188for (size_t i = 0; i < page_count; i++)189{190const Mat page = imread(root + page_files[i], mode);191EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), page, pages[i]);192}193}194195const int all_modes[] =196{197IMREAD_UNCHANGED,198IMREAD_GRAYSCALE,199IMREAD_COLOR,200IMREAD_ANYDEPTH,201IMREAD_ANYCOLOR202};203204INSTANTIATE_TEST_CASE_P(AllModes, Imgcodecs_Tiff_Modes, testing::ValuesIn(all_modes));205206//==================================================================================================207208TEST(Imgcodecs_Tiff_Modes, write_multipage)209{210const string root = cvtest::TS::ptr()->get_data_path();211const string filename = root + "readwrite/multipage.tif";212const string page_files[] = {213"readwrite/multipage_p1.tif",214"readwrite/multipage_p2.tif",215"readwrite/multipage_p3.tif",216"readwrite/multipage_p4.tif",217"readwrite/multipage_p5.tif",218"readwrite/multipage_p6.tif"219};220const size_t page_count = sizeof(page_files) / sizeof(page_files[0]);221vector<Mat> pages;222for (size_t i = 0; i < page_count; i++)223{224const Mat page = imread(root + page_files[i]);225pages.push_back(page);226}227228string tmp_filename = cv::tempfile(".tiff");229bool res = imwrite(tmp_filename, pages);230ASSERT_TRUE(res);231232vector<Mat> read_pages;233imreadmulti(tmp_filename, read_pages);234for (size_t i = 0; i < page_count; i++)235{236EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), read_pages[i], pages[i]);237}238}239240//==================================================================================================241242TEST(Imgcodecs_Tiff, imdecode_no_exception_temporary_file_removed)243{244const string root = cvtest::TS::ptr()->get_data_path();245const string filename = root + "../cv/shared/lena.png";246cv::Mat img = cv::imread(filename);247ASSERT_FALSE(img.empty());248std::vector<uchar> buf;249EXPECT_NO_THROW(cv::imencode(".tiff", img, buf));250EXPECT_NO_THROW(cv::imdecode(buf, IMREAD_UNCHANGED));251}252253#endif254255}} // namespace256257258