diff --git a/modules/imgcodecs/src/grfmt_tiff.cpp b/modules/imgcodecs/src/grfmt_tiff.cpp index 6bbb9ebd05..a46ed3ac90 100644 --- a/modules/imgcodecs/src/grfmt_tiff.cpp +++ b/modules/imgcodecs/src/grfmt_tiff.cpp @@ -273,7 +273,11 @@ bool TiffDecoder::readHeader() { bool isGrayScale = photometric == PHOTOMETRIC_MINISWHITE || photometric == PHOTOMETRIC_MINISBLACK; uint16 bpp = 8, ncn = isGrayScale ? 1 : 3; - CV_TIFF_CHECK_CALL(TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp)); + if (0 == TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp)) + { + // TIFF bi-level images don't require TIFFTAG_BITSPERSAMPLE tag + bpp = 1; + } CV_TIFF_CHECK_CALL_DEBUG(TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &ncn)); m_width = wdth; @@ -430,7 +434,11 @@ bool TiffDecoder::readData( Mat& img ) int is_tiled = TIFFIsTiled(tif) != 0; bool isGrayScale = photometric == PHOTOMETRIC_MINISWHITE || photometric == PHOTOMETRIC_MINISBLACK; uint16 bpp = 8, ncn = isGrayScale ? 1 : 3; - CV_TIFF_CHECK_CALL(TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp)); + if (0 == TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp)) + { + // TIFF bi-level images don't require TIFFTAG_BITSPERSAMPLE tag + bpp = 1; + } CV_TIFF_CHECK_CALL_DEBUG(TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &ncn)); uint16 img_orientation = ORIENTATION_TOPLEFT; CV_TIFF_CHECK_CALL_DEBUG(TIFFGetField(tif, TIFFTAG_ORIENTATION, &img_orientation)); diff --git a/modules/imgcodecs/test/test_tiff.cpp b/modules/imgcodecs/test/test_tiff.cpp index add15ff681..2c6fb6249b 100644 --- a/modules/imgcodecs/test/test_tiff.cpp +++ b/modules/imgcodecs/test/test_tiff.cpp @@ -308,7 +308,7 @@ TEST(Imgcodecs_Tiff, imdecode_no_exception_temporary_file_removed) } -TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr12989) +TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr12989_grayscale) { const string filename = cvtest::findDataFile("readwrite/bitsperpixel1.tiff"); cv::Mat img; @@ -333,6 +333,31 @@ TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr12989_default) EXPECT_EQ(CV_8UC3, img.type()) << cv::typeToString(img.type()); } +TEST(Imgcodecs_Tiff, decode_black_and_write_image_pr17275_grayscale) +{ + const string filename = cvtest::findDataFile("readwrite/bitsperpixel1_min.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_pr17275_default) +{ + const string filename = cvtest::findDataFile("readwrite/bitsperpixel1_min.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