added 16-bit support to TiffEncoder

pull/13383/head
Vladislav Vinogradov 14 years ago
parent f385bb97eb
commit 604c53a0ab
  1. 36
      modules/highgui/src/grfmt_tiff.cpp
  2. 2
      modules/highgui/src/grfmt_tiff.hpp
  3. 19
      modules/highgui/src/utils.cpp
  4. 4
      modules/highgui/src/utils.hpp

@ -301,6 +301,11 @@ TiffEncoder::~TiffEncoder()
{ {
} }
bool TiffEncoder::isFormatSupported( int depth ) const
{
return depth == CV_8U || depth == CV_16U;
}
ImageEncoder TiffEncoder::newEncoder() const ImageEncoder TiffEncoder::newEncoder() const
{ {
return new TiffEncoder; return new TiffEncoder;
@ -321,7 +326,13 @@ bool TiffEncoder::write( const Mat& img, const vector<int>& )
{ {
int channels = img.channels(); int channels = img.channels();
int width = img.cols, height = img.rows; 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; WLByteStream strm;
if( m_buf ) if( m_buf )
@ -356,7 +367,7 @@ bool TiffEncoder::write( const Mat& img, const vector<int>& )
uchar* buffer = _buffer; uchar* buffer = _buffer;
int stripOffsetsOffset = 0; int stripOffsetsOffset = 0;
int stripCountsOffset = 0; int stripCountsOffset = 0;
int bitsPerSample = 8; // TODO support 16 bit int bitsPerSample = 8 * bytesPerChannel;
int y = 0; int y = 0;
strm.putBytes( fmtSignTiffII, 4 ); strm.putBytes( fmtSignTiffII, 4 );
@ -376,9 +387,15 @@ bool TiffEncoder::write( const Mat& img, const vector<int>& )
for( ; y < limit; y++ ) for( ; y < limit; y++ )
{ {
if( channels == 3 ) 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 ) 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 ); strm.putBytes( channels > 1 ? buffer : img.data + img.step*y, fileStep );
} }
@ -416,12 +433,13 @@ bool TiffEncoder::write( const Mat& img, const vector<int>& )
if( channels > 1 ) if( channels > 1 )
{ {
bitsPerSample = strm.getPos(); int bitsPerSamplePos = strm.getPos();
strm.putWord(8); strm.putWord(bitsPerSample);
strm.putWord(8); strm.putWord(bitsPerSample);
strm.putWord(8); strm.putWord(bitsPerSample);
if( channels == 4 ) if( channels == 4 )
strm.putWord(8); strm.putWord(bitsPerSample);
bitsPerSample = bitsPerSamplePos;
} }
directoryOffset = strm.getPos(); directoryOffset = strm.getPos();

@ -118,6 +118,8 @@ public:
TiffEncoder(); TiffEncoder();
virtual ~TiffEncoder(); virtual ~TiffEncoder();
bool isFormatSupported( int depth ) const;
bool write( const Mat& img, const vector<int>& params ); bool write( const Mat& img, const vector<int>& params );
ImageEncoder newEncoder() const; ImageEncoder newEncoder() const;

@ -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, void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step,
uchar* rgb, int rgb_step, CvSize size ) uchar* rgb, int rgb_step, CvSize size )

@ -88,6 +88,10 @@ void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step,
uchar* rgba, int rgba_step, CvSize size ); uchar* rgba, int rgba_step, CvSize size );
#define icvCvt_RGBA2BGRA_8u_C4R icvCvt_BGRA2RGBA_8u_C4R #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, void icvCvt_BGR5552Gray_8u_C2C1R( const uchar* bgr555, int bgr555_step,
uchar* gray, int gray_step, CvSize size ); uchar* gray, int gray_step, CvSize size );
void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step, void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step,

Loading…
Cancel
Save