From 604c53a0abd1a5051f8e97d5fbba419206525dd9 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Thu, 21 Apr 2011 08:16:23 +0000 Subject: [PATCH] added 16-bit support to TiffEncoder --- modules/highgui/src/grfmt_tiff.cpp | 36 ++++++++++++++++++++++-------- modules/highgui/src/grfmt_tiff.hpp | 2 ++ modules/highgui/src/utils.cpp | 19 ++++++++++++++++ modules/highgui/src/utils.hpp | 4 ++++ 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/modules/highgui/src/grfmt_tiff.cpp b/modules/highgui/src/grfmt_tiff.cpp index dfb4db26fa..b96090d650 100644 --- a/modules/highgui/src/grfmt_tiff.cpp +++ b/modules/highgui/src/grfmt_tiff.cpp @@ -301,6 +301,11 @@ TiffEncoder::~TiffEncoder() { } +bool TiffEncoder::isFormatSupported( int depth ) const +{ + return depth == CV_8U || depth == CV_16U; +} + ImageEncoder TiffEncoder::newEncoder() const { return new TiffEncoder; @@ -321,7 +326,13 @@ bool TiffEncoder::write( const Mat& img, const vector& ) { int channels = img.channels(); int width = img.cols, height = img.rows; - int fileStep = width*channels; + int depth = img.depth(); + + if (depth != CV_8U && depth != CV_16U) + return false; + + int bytesPerChannel = depth == CV_8U ? 1 : 2; + int fileStep = width * channels * bytesPerChannel; WLByteStream strm; if( m_buf ) @@ -356,7 +367,7 @@ bool TiffEncoder::write( const Mat& img, const vector& ) uchar* buffer = _buffer; int stripOffsetsOffset = 0; int stripCountsOffset = 0; - int bitsPerSample = 8; // TODO support 16 bit + int bitsPerSample = 8 * bytesPerChannel; int y = 0; strm.putBytes( fmtSignTiffII, 4 ); @@ -376,9 +387,15 @@ bool TiffEncoder::write( const Mat& img, const vector& ) for( ; y < limit; y++ ) { if( channels == 3 ) - icvCvt_BGR2RGB_8u_C3R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) ); + if (depth == CV_8U) + icvCvt_BGR2RGB_8u_C3R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) ); + else + icvCvt_BGR2RGB_16u_C3R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) ); else if( channels == 4 ) - icvCvt_BGRA2RGBA_8u_C4R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) ); + if (depth == CV_8U) + icvCvt_BGRA2RGBA_8u_C4R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) ); + else + icvCvt_BGRA2RGBA_16u_C4R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) ); strm.putBytes( channels > 1 ? buffer : img.data + img.step*y, fileStep ); } @@ -416,12 +433,13 @@ bool TiffEncoder::write( const Mat& img, const vector& ) if( channels > 1 ) { - bitsPerSample = strm.getPos(); - strm.putWord(8); - strm.putWord(8); - strm.putWord(8); + int bitsPerSamplePos = strm.getPos(); + strm.putWord(bitsPerSample); + strm.putWord(bitsPerSample); + strm.putWord(bitsPerSample); if( channels == 4 ) - strm.putWord(8); + strm.putWord(bitsPerSample); + bitsPerSample = bitsPerSamplePos; } directoryOffset = strm.getPos(); diff --git a/modules/highgui/src/grfmt_tiff.hpp b/modules/highgui/src/grfmt_tiff.hpp index 877c229789..037739a8df 100644 --- a/modules/highgui/src/grfmt_tiff.hpp +++ b/modules/highgui/src/grfmt_tiff.hpp @@ -118,6 +118,8 @@ public: TiffEncoder(); virtual ~TiffEncoder(); + bool isFormatSupported( int depth ) const; + bool write( const Mat& img, const vector& params ); ImageEncoder newEncoder() const; diff --git a/modules/highgui/src/utils.cpp b/modules/highgui/src/utils.cpp index 4197b90b94..e4b2a22bd7 100644 --- a/modules/highgui/src/utils.cpp +++ b/modules/highgui/src/utils.cpp @@ -192,6 +192,25 @@ void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step, } } +void icvCvt_BGRA2RGBA_16u_C4R( const ushort* bgra, int bgra_step, + ushort* rgba, int rgba_step, CvSize size ) +{ + int i; + for( ; size.height--; ) + { + for( i = 0; i < size.width; i++, bgra += 4, rgba += 4 ) + { + ushort t0 = bgra[0], t1 = bgra[1]; + ushort t2 = bgra[2], t3 = bgra[3]; + + rgba[0] = t2; rgba[1] = t1; + rgba[2] = t0; rgba[3] = t3; + } + bgra += bgra_step/sizeof(bgra[0]) - size.width*4; + rgba += rgba_step/sizeof(rgba[0]) - size.width*4; + } +} + void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step, uchar* rgb, int rgb_step, CvSize size ) diff --git a/modules/highgui/src/utils.hpp b/modules/highgui/src/utils.hpp index 5eba19aed2..0c942c4a4e 100644 --- a/modules/highgui/src/utils.hpp +++ b/modules/highgui/src/utils.hpp @@ -88,6 +88,10 @@ void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step, uchar* rgba, int rgba_step, CvSize size ); #define icvCvt_RGBA2BGRA_8u_C4R icvCvt_BGRA2RGBA_8u_C4R +void icvCvt_BGRA2RGBA_16u_C4R( const ushort* bgra, int bgra_step, + ushort* rgba, int rgba_step, CvSize size ); +#define icvCvt_RGBA2BGRA_16u_C4R icvCvt_BGRA2RGBA_16u_C4R + void icvCvt_BGR5552Gray_8u_C2C1R( const uchar* bgr555, int bgr555_step, uchar* gray, int gray_step, CvSize size ); void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step,