From 7927ebf20eae7e265904e4665645331d8a2860ca Mon Sep 17 00:00:00 2001 From: kobigurk Date: Sun, 10 Feb 2013 01:22:49 +0200 Subject: [PATCH 1/5] alpha channels support for 8-bit tiffs --- modules/highgui/src/grfmt_tiff.cpp | 22 ++++++++++++++++++++-- modules/highgui/src/grfmt_tiff.hpp | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/modules/highgui/src/grfmt_tiff.cpp b/modules/highgui/src/grfmt_tiff.cpp index 5179531f50..6258e46d56 100644 --- a/modules/highgui/src/grfmt_tiff.cpp +++ b/modules/highgui/src/grfmt_tiff.cpp @@ -101,6 +101,11 @@ bool TiffDecoder::checkSignature( const string& signature ) const memcmp(signature.c_str(), fmtSignTiffMM, 4) == 0); } +int TiffDecoder::normalizeChannelsNumber(int channels) const +{ + return channels > 4 ? 4 : channels; +} + ImageDecoder TiffDecoder::newDecoder() const { return new TiffDecoder; @@ -133,10 +138,11 @@ bool TiffDecoder::readHeader() (ncn != 1 && ncn != 3 && ncn != 4))) bpp = 8; + int wanted_channels = normalizeChannelsNumber(ncn); switch(bpp) { case 8: - m_type = CV_MAKETYPE(CV_8U, photometric > 1 ? 3 : 1); + m_type = CV_MAKETYPE(CV_8U, photometric > 1 ? wanted_channels : 1); break; case 16: m_type = CV_MAKETYPE(CV_16U, photometric > 1 ? 3 : 1); @@ -185,6 +191,7 @@ bool TiffDecoder::readData( Mat& img ) TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn ); const int bitsPerByte = 8; int dst_bpp = (int)(img.elemSize1() * bitsPerByte); + int wanted_channels = normalizeChannelsNumber(img.channels()); if(dst_bpp == 8) { @@ -248,9 +255,20 @@ bool TiffDecoder::readData( Mat& img ) for( i = 0; i < tile_height; i++ ) if( color ) - icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0, + { + if (wanted_channels == 4) + { + icvCvt_BGRA2RGBA_8u_C4R( buffer + i*tile_width*4, 0, + data + x*4 + img.step*(tile_height - i - 1), 0, + cvSize(tile_width,1) ); + } + else + { + icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0, data + x*3 + img.step*(tile_height - i - 1), 0, cvSize(tile_width,1), 2 ); + } + } else icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0, data + x + img.step*(tile_height - i - 1), 0, diff --git a/modules/highgui/src/grfmt_tiff.hpp b/modules/highgui/src/grfmt_tiff.hpp index 831854828f..6cf77302e5 100644 --- a/modules/highgui/src/grfmt_tiff.hpp +++ b/modules/highgui/src/grfmt_tiff.hpp @@ -103,6 +103,7 @@ public: size_t signatureLength() const; bool checkSignature( const string& signature ) const; + int normalizeChannelsNumber(int channels) const; ImageDecoder newDecoder() const; protected: From 9f80c6c9894588ab1f4c8441d33e7357e924ba97 Mon Sep 17 00:00:00 2001 From: kobigurk Date: Tue, 12 Feb 2013 11:21:51 +0200 Subject: [PATCH 2/5] added test for 4 channel tiff --- modules/highgui/test/test_grfmt.cpp | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/modules/highgui/test/test_grfmt.cpp b/modules/highgui/test/test_grfmt.cpp index 8366fcdffc..d431d964dd 100644 --- a/modules/highgui/test/test_grfmt.cpp +++ b/modules/highgui/test/test_grfmt.cpp @@ -124,6 +124,36 @@ public: ts->set_failed_test_info(ts->FAIL_MISMATCH); } } + if (ext == 3 /*TIFF*/) + { + /* 4 channels should stay 4 channels */ + int num_channels = 4; + ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U,num_channels, ext_from_int(ext).c_str()); + Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0)); + circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); + + string img_path = cv::tempfile(ext_from_int(ext).c_str()); + ts->printf(ts->LOG, "writing image : %s\n", img_path.c_str()); + imwrite(img_path, img); + + ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str()); + Mat img_test = imread(img_path, CV_LOAD_IMAGE_UNCHANGED); + + if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH); + + CV_Assert(img.size() == img_test.size()); + CV_Assert(img.type() == img_test.type()); + CV_Assert(img.channels() == 4); + + double n = norm(img, img_test); + if ( n > 1.0) + { + ts->printf(ts->LOG, "norm = %f \n", n); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + } + + } + } #ifdef HAVE_JPEG From 109e047a283e65424463bc16813f242e5612a483 Mon Sep 17 00:00:00 2001 From: kobigurk Date: Wed, 13 Feb 2013 13:33:07 +0200 Subject: [PATCH 3/5] * img_test is now tested for channel numbers instead of img * fixed indentation to use spaces and trailing spaces --- modules/highgui/test/test_grfmt.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/highgui/test/test_grfmt.cpp b/modules/highgui/test/test_grfmt.cpp index d431d964dd..a3ce110a7e 100644 --- a/modules/highgui/test/test_grfmt.cpp +++ b/modules/highgui/test/test_grfmt.cpp @@ -124,10 +124,10 @@ public: ts->set_failed_test_info(ts->FAIL_MISMATCH); } } - if (ext == 3 /*TIFF*/) + if (ext == 3 /*TIFF*/) { /* 4 channels should stay 4 channels */ - int num_channels = 4; + int num_channels = 4; ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U,num_channels, ext_from_int(ext).c_str()); Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0)); circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); @@ -143,7 +143,7 @@ public: CV_Assert(img.size() == img_test.size()); CV_Assert(img.type() == img_test.type()); - CV_Assert(img.channels() == 4); + CV_Assert(img_test.channels() == 4); double n = norm(img, img_test); if ( n > 1.0) @@ -153,7 +153,6 @@ public: } } - } #ifdef HAVE_JPEG From 88e0127f44e6da485ba257da324a72bcbc8478ae Mon Sep 17 00:00:00 2001 From: kobigurk Date: Wed, 13 Feb 2013 14:13:36 +0200 Subject: [PATCH 4/5] API of TiffDecoder back to what it was - normalizeChannelsNumber moved to protected test code unified - channels number is tested for other formats as well --- modules/highgui/src/grfmt_tiff.hpp | 2 +- modules/highgui/test/test_grfmt.cpp | 35 +++++------------------------ 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/modules/highgui/src/grfmt_tiff.hpp b/modules/highgui/src/grfmt_tiff.hpp index 6cf77302e5..557b10c3c8 100644 --- a/modules/highgui/src/grfmt_tiff.hpp +++ b/modules/highgui/src/grfmt_tiff.hpp @@ -103,11 +103,11 @@ public: size_t signatureLength() const; bool checkSignature( const string& signature ) const; - int normalizeChannelsNumber(int channels) const; ImageDecoder newDecoder() const; protected: void* m_tif; + int normalizeChannelsNumber(int channels) const; }; #endif diff --git a/modules/highgui/test/test_grfmt.cpp b/modules/highgui/test/test_grfmt.cpp index a3ce110a7e..a7eb0c7762 100644 --- a/modules/highgui/test/test_grfmt.cpp +++ b/modules/highgui/test/test_grfmt.cpp @@ -99,8 +99,11 @@ public: { if(ext_from_int(ext).empty()) continue; - for (int num_channels = 1; num_channels <= 3; num_channels+=2) + for (int num_channels = 1; num_channels <= 4; num_channels++) { + if (num_channels == 2) continue; + if (num_channels == 4 && ext!=3 /*TIFF*/) continue; + ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U, num_channels, ext_from_int(ext).c_str()); Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0)); circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); @@ -116,6 +119,7 @@ public: CV_Assert(img.size() == img_test.size()); CV_Assert(img.type() == img_test.type()); + CV_Assert(num_channels == img_test.channels()); double n = norm(img, img_test); if ( n > 1.0) @@ -124,35 +128,6 @@ public: ts->set_failed_test_info(ts->FAIL_MISMATCH); } } - if (ext == 3 /*TIFF*/) - { - /* 4 channels should stay 4 channels */ - int num_channels = 4; - ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U,num_channels, ext_from_int(ext).c_str()); - Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0)); - circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); - - string img_path = cv::tempfile(ext_from_int(ext).c_str()); - ts->printf(ts->LOG, "writing image : %s\n", img_path.c_str()); - imwrite(img_path, img); - - ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str()); - Mat img_test = imread(img_path, CV_LOAD_IMAGE_UNCHANGED); - - if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH); - - CV_Assert(img.size() == img_test.size()); - CV_Assert(img.type() == img_test.type()); - CV_Assert(img_test.channels() == 4); - - double n = norm(img, img_test); - if ( n > 1.0) - { - ts->printf(ts->LOG, "norm = %f \n", n); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - } - - } } #ifdef HAVE_JPEG From 18a5b8dfc645325f180d8738009caa37376db5fc Mon Sep 17 00:00:00 2001 From: kobigurk Date: Wed, 13 Feb 2013 14:21:34 +0200 Subject: [PATCH 5/5] fixed tab indent --- modules/highgui/test/test_grfmt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/highgui/test/test_grfmt.cpp b/modules/highgui/test/test_grfmt.cpp index a7eb0c7762..7a9becca28 100644 --- a/modules/highgui/test/test_grfmt.cpp +++ b/modules/highgui/test/test_grfmt.cpp @@ -101,8 +101,8 @@ public: continue; for (int num_channels = 1; num_channels <= 4; num_channels++) { - if (num_channels == 2) continue; - if (num_channels == 4 && ext!=3 /*TIFF*/) continue; + if (num_channels == 2) continue; + if (num_channels == 4 && ext!=3 /*TIFF*/) continue; ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U, num_channels, ext_from_int(ext).c_str()); Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));