From c3e27bcf8746d2aaa093664b734f913678df0f5b Mon Sep 17 00:00:00 2001 From: Harvey <619328684@qq.com> Date: Wed, 12 Jan 2022 00:51:50 +0800 Subject: [PATCH] Merge pull request #21400 from Harvey-Huang:master tiff need check TIFFTAG_SAMPLEFORMAT, should not always use unsigned. --- modules/imgcodecs/src/grfmt_tiff.cpp | 75 +++++++++++++++++----------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/modules/imgcodecs/src/grfmt_tiff.cpp b/modules/imgcodecs/src/grfmt_tiff.cpp index 5e7523b203..e8744f13b9 100644 --- a/modules/imgcodecs/src/grfmt_tiff.cpp +++ b/modules/imgcodecs/src/grfmt_tiff.cpp @@ -295,34 +295,53 @@ bool TiffDecoder::readHeader() (ncn != 1 && ncn != 3 && ncn != 4))) bpp = 8; + uint16 sample_format = SAMPLEFORMAT_UINT; + TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sample_format); int wanted_channels = normalizeChannelsNumber(ncn); - switch(bpp) + switch (bpp) { - case 1: - m_type = CV_MAKETYPE(CV_8U, !isGrayScale ? wanted_channels : 1); - result = true; - break; - case 8: - //Palette color, the value of the component is used as an index into the red, - //green and blue curves in the ColorMap field to retrieve an RGB triplet that defines the color. - if(photometric == PHOTOMETRIC_PALETTE) - m_type = CV_MAKETYPE(CV_8U, 3); - else - m_type = CV_MAKETYPE(CV_8U, !isGrayScale ? wanted_channels : 1); - result = true; - break; - case 16: - m_type = CV_MAKETYPE(CV_16U, !isGrayScale ? wanted_channels : 1); - result = true; - break; - case 32: - m_type = CV_MAKETYPE(CV_32F, wanted_channels); - result = true; - break; - case 64: - m_type = CV_MAKETYPE(CV_64F, wanted_channels); - result = true; - break; + case 1: + { + CV_Check((int)sample_format, sample_format == SAMPLEFORMAT_UINT || sample_format == SAMPLEFORMAT_INT, ""); + int depth = sample_format == SAMPLEFORMAT_INT ? CV_8S : CV_8U; + m_type = CV_MAKETYPE(depth, !isGrayScale ? wanted_channels : 1); + result = true; + break; + } + case 8: + { + //Palette color, the value of the component is used as an index into the red, + //green and blue curves in the ColorMap field to retrieve an RGB triplet that defines the color. + CV_Check((int)sample_format, sample_format == SAMPLEFORMAT_UINT || sample_format == SAMPLEFORMAT_INT, ""); + int depth = sample_format == SAMPLEFORMAT_INT ? CV_8S : CV_8U; + if (photometric == PHOTOMETRIC_PALETTE) + m_type = CV_MAKETYPE(depth, 3); + else + m_type = CV_MAKETYPE(depth, !isGrayScale ? wanted_channels : 1); + result = true; + break; + } + case 16: + { + CV_Check((int)sample_format, sample_format == SAMPLEFORMAT_UINT || sample_format == SAMPLEFORMAT_INT, ""); + int depth = sample_format == SAMPLEFORMAT_INT ? CV_16S : CV_16U; + m_type = CV_MAKETYPE(depth, !isGrayScale ? wanted_channels : 1); + result = true; + break; + } + case 32: + { + CV_Check((int)sample_format, sample_format == SAMPLEFORMAT_IEEEFP || sample_format == SAMPLEFORMAT_INT, ""); + int depth = sample_format == SAMPLEFORMAT_IEEEFP ? CV_32F : CV_32S; + m_type = CV_MAKETYPE(depth, wanted_channels); + result = true; + break; + } + case 64: + CV_CheckEQ((int)sample_format, SAMPLEFORMAT_IEEEFP, ""); + m_type = CV_MAKETYPE(CV_64F, wanted_channels); + result = true; + break; default: CV_Error(cv::Error::StsError, "Invalid bitsperpixel value read from TIFF header! Must be 1, 8, 16, 32 or 64."); } @@ -432,7 +451,7 @@ bool TiffDecoder::readData( Mat& img ) bool color = img.channels() > 1; - CV_CheckType(type, depth == CV_8U || depth == CV_16U || depth == CV_32F || depth == CV_64F, ""); + CV_CheckType(type, depth == CV_8U || depth == CV_8S || depth == CV_16U || depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F, ""); if (m_width && m_height) { @@ -649,7 +668,7 @@ bool TiffDecoder::readData( Mat& img ) CV_TIFF_CHECK_CALL((int)TIFFReadEncodedTile(tif, tileidx, buffer, buffer_size) >= 0); } - Mat m_tile(Size(tile_width0, tile_height0), CV_MAKETYPE((dst_bpp == 32) ? CV_32F : CV_64F, ncn), buffer); + Mat m_tile(Size(tile_width0, tile_height0), CV_MAKETYPE((dst_bpp == 32) ? (depth == CV_32S ? CV_32S : CV_32F) : CV_64F, ncn), buffer); Rect roi_tile(0, 0, tile_width, tile_height); Rect roi_img(x, img_y, tile_width, tile_height); if (!m_hdr && ncn == 3)