1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

Merge pull request #23433 from Kumataro:4.x-fix23416

imgcodecs: tiff: Support to encode for CV_32S with compression params

Fix https://github.com/opencv/opencv/issues/23416

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Kumataro
2023-04-11 16:50:47 +09:00
committed by GitHub
parent 88a7e8cdf5
commit d2dbaa4cd1
2 changed files with 160 additions and 7 deletions
+65 -7
View File
@@ -63,6 +63,9 @@ using namespace tiff_dummy_namespace;
namespace cv
{
// to extend cvtColor() to support CV_8S, CV_16S, CV_32S and CV_64F.
static void extend_cvtColor( InputArray _src, OutputArray _dst, int code );
#define CV_TIFF_CHECK_CALL(call) \
if (0 == (call)) { \
CV_LOG_WARNING(NULL, "OpenCV TIFF(line " << __LINE__ << "): failed " #call); \
@@ -1039,9 +1042,9 @@ bool TiffDecoder::readData( Mat& img )
Rect roi_tile(0, 0, tile_width, tile_height);
Rect roi_img(x, img_y, tile_width, tile_height);
if (!m_hdr && ncn == 3)
cvtColor(m_tile(roi_tile), img(roi_img), COLOR_RGB2BGR);
extend_cvtColor(m_tile(roi_tile), img(roi_img), COLOR_RGB2BGR);
else if (!m_hdr && ncn == 4)
cvtColor(m_tile(roi_tile), img(roi_img), COLOR_RGBA2BGRA);
extend_cvtColor(m_tile(roi_tile), img(roi_img), COLOR_RGBA2BGRA);
else
m_tile(roi_tile).copyTo(img(roi_img));
break;
@@ -1279,13 +1282,17 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
break;
}
case CV_32F:
sample_format = SAMPLEFORMAT_IEEEFP;
/* FALLTHRU */
case CV_32S:
{
bitsPerChannel = 32;
sample_format = SAMPLEFORMAT_INT;
break;
}
case CV_32F:
{
bitsPerChannel = 32;
page_compression = COMPRESSION_NONE;
sample_format = SAMPLEFORMAT_IEEEFP;
break;
}
case CV_64F:
@@ -1356,13 +1363,13 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
case 3:
{
cvtColor(img(Rect(0, y, width, 1)), (const Mat&)m_buffer, COLOR_BGR2RGB);
extend_cvtColor(img(Rect(0, y, width, 1)), (const Mat&)m_buffer, COLOR_BGR2RGB);
break;
}
case 4:
{
cvtColor(img(Rect(0, y, width, 1)), (const Mat&)m_buffer, COLOR_BGRA2RGBA);
extend_cvtColor(img(Rect(0, y, width, 1)), (const Mat&)m_buffer, COLOR_BGRA2RGBA);
break;
}
@@ -1424,6 +1431,57 @@ bool TiffEncoder::write( const Mat& img, const std::vector<int>& params)
return writeLibTiff(img_vec, params);
}
static void extend_cvtColor( InputArray _src, OutputArray _dst, int code )
{
CV_Assert( !_src.empty() );
CV_Assert( _src.dims() == 2 );
// This function extend_cvtColor reorders the src channels with only thg limited condition.
// Otherwise, it calls cvtColor.
const int stype = _src.type();
if(!
(
(
( stype == CV_8SC3 ) || ( stype == CV_8SC4 ) ||
( stype == CV_16SC3 ) || ( stype == CV_16SC4 ) ||
( stype == CV_32SC3 ) || ( stype == CV_32SC4 ) ||
( stype == CV_64FC3 ) || ( stype == CV_64FC4 )
)
&&
(
( code == COLOR_BGR2RGB ) || ( code == COLOR_BGRA2RGBA )
)
)
)
{
cvtColor( _src, _dst, code );
return;
}
Mat src = _src.getMat();
// cv::mixChannels requires the output arrays to be pre-allocated before calling the function.
_dst.create( _src.size(), stype );
Mat dst = _dst.getMat();
// BGR to RGB or BGRA to RGBA
// src[0] -> dst[2]
// src[1] -> dst[1]
// src[2] -> dst[0]
// src[3] -> dst[3] if src has alpha channel.
std::vector<int> fromTo;
fromTo.push_back(0); fromTo.push_back(2);
fromTo.push_back(1); fromTo.push_back(1);
fromTo.push_back(2); fromTo.push_back(0);
if ( code == COLOR_BGRA2RGBA )
{
fromTo.push_back(3); fromTo.push_back(3);
}
cv::mixChannels( src, dst, fromTo );
}
} // namespace
#endif