From e6c41f0de60f6f032560ec2089f6f04d71766b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilari=20Ven=C3=A4l=C3=A4inen?= Date: Thu, 1 Nov 2018 13:34:34 +0200 Subject: [PATCH] Merge pull request #12989 from venalil:fix_thresholded_tiff_read * Fix reading of black-and-white (thresholded) TIFF images I recently updated my local OpenCV version to 3.4.3 and found out that I could not read my TIFF images related to my project. After debugging I found out that there has been some static analysis fixes made that accidentally have broken reading those black-and-white TIFF images. Commit hash in which reading of mentioned TIFF images has been broken: cbb1e867e5141412c62ff534def7f117e28e04e8 Basically the fix is to revert back to the same functionality that has been there before, when black-and-white images are read bpp (bitspersample) is 1. Without the case 1: this TiffDecoder::readHeader() function always return false. * Added type and default error message * Added stdexcept include * Use CV_Error instead of throw std::runtime_error * imgcodecs(test): add TIFF B/W decoding tests --- modules/imgcodecs/src/grfmt_tiff.cpp | 6 ++++++ modules/imgcodecs/test/test_tiff.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/modules/imgcodecs/src/grfmt_tiff.cpp b/modules/imgcodecs/src/grfmt_tiff.cpp index 69dc4261ac..b83ab1068a 100644 --- a/modules/imgcodecs/src/grfmt_tiff.cpp +++ b/modules/imgcodecs/src/grfmt_tiff.cpp @@ -253,6 +253,10 @@ bool TiffDecoder::readHeader() int wanted_channels = normalizeChannelsNumber(ncn); switch(bpp) { + case 1: + m_type = CV_MAKETYPE(CV_8U, photometric > 1 ? wanted_channels : 1); + result = true; + break; case 8: m_type = CV_MAKETYPE(CV_8U, photometric > 1 ? wanted_channels : 1); result = true; @@ -269,6 +273,8 @@ bool TiffDecoder::readHeader() m_type = CV_MAKETYPE(CV_64F, photometric > 1 ? 3 : 1); result = true; break; + default: + CV_Error(cv::Error::StsError, "Invalid bitsperpixel value read from TIFF header! Must be 1, 8, 16, 32 or 64."); } } } diff --git a/modules/imgcodecs/test/test_tiff.cpp b/modules/imgcodecs/test/test_tiff.cpp index 1f5ab2401a..0c9d7ae908 100644 --- a/modules/imgcodecs/test/test_tiff.cpp +++ b/modules/imgcodecs/test/test_tiff.cpp @@ -251,6 +251,32 @@ TEST(Imgcodecs_Tiff, imdecode_no_exception_temporary_file_removed) EXPECT_NO_THROW(cv::imdecode(buf, IMREAD_UNCHANGED)); } + +TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr12989) +{ + const string filename = cvtest::findDataFile("readwrite/bitsperpixel1.tiff"); + cv::Mat img; + ASSERT_NO_THROW(img = cv::imread(filename, IMREAD_GRAYSCALE)); + ASSERT_FALSE(img.empty()); + EXPECT_EQ(64, img.cols); + EXPECT_EQ(64, img.rows); + EXPECT_EQ(CV_8UC1, img.type()) << cv::typeToString(img.type()); + // Check for 0/255 values only: 267 + 3829 = 64*64 + EXPECT_EQ(267, countNonZero(img == 0)); + EXPECT_EQ(3829, countNonZero(img == 255)); +} + +TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr12989_default) +{ + const string filename = cvtest::findDataFile("readwrite/bitsperpixel1.tiff"); + cv::Mat img; + ASSERT_NO_THROW(img = cv::imread(filename)); // by default image type is CV_8UC3 + ASSERT_FALSE(img.empty()); + EXPECT_EQ(64, img.cols); + EXPECT_EQ(64, img.rows); + EXPECT_EQ(CV_8UC3, img.type()) << cv::typeToString(img.type()); +} + #endif }} // namespace