From afb164cc15e42b87e5647b2b03f3967d4e20a6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20St=C3=BChrk?= Date: Wed, 8 Oct 2014 23:31:30 +0200 Subject: [PATCH] Don't allocate lots of memory when reading TIFFs with infinite rows per strip. Some TIFF images consist of only one strip. The magic value 2**32-1 for the "rows per strip" tag reflects that fact, effectively meaning "infinite". --- modules/highgui/src/grfmt_tiff.cpp | 3 ++- modules/highgui/test/test_grfmt.cpp | 33 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/modules/highgui/src/grfmt_tiff.cpp b/modules/highgui/src/grfmt_tiff.cpp index f40699f83..ac36a55ae 100644 --- a/modules/highgui/src/grfmt_tiff.cpp +++ b/modules/highgui/src/grfmt_tiff.cpp @@ -210,7 +210,8 @@ bool TiffDecoder::readData( Mat& img ) if( tile_width0 <= 0 ) tile_width0 = m_width; - if( tile_height0 <= 0 ) + if( tile_height0 <= 0 || + (!is_tiled && tile_height0 == std::numeric_limits::max()) ) tile_height0 = m_height; AutoBuffer _buffer( size_t(8) * tile_height0*tile_width0); diff --git a/modules/highgui/test/test_grfmt.cpp b/modules/highgui/test/test_grfmt.cpp index aa1a84506..1e47e57ce 100644 --- a/modules/highgui/test/test_grfmt.cpp +++ b/modules/highgui/test/test_grfmt.cpp @@ -43,6 +43,8 @@ #include "test_precomp.hpp" #include "opencv2/highgui/highgui.hpp" +#include + using namespace cv; using namespace std; @@ -514,4 +516,35 @@ TEST(Highgui_Tiff, decode_tile_remainder) CV_GrfmtReadTifTiledWithNotFullTiles test; test.safe_run(); } +TEST(Imgcodecs_Tiff, decode_infinite_rowsperstrip) +{ + const uchar sample_data[142] = { + 0x49, 0x49, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x56, 0x54, + 0x56, 0x5a, 0x59, 0x55, 0x5a, 0x00, 0x0a, 0x00, 0x00, 0x01, + 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x01, 0x03, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 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, + 0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x03, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 + }; + + const string filename = cv::tempfile(".tiff"); + std::ofstream outfile(filename.c_str(), std::ofstream::binary); + outfile.write(reinterpret_cast(sample_data), sizeof sample_data); + outfile.close(); + + EXPECT_NO_THROW(cv::imread(filename, IMREAD_UNCHANGED)); + + remove(filename.c_str()); +} + + #endif