strm.putDWord( value );
}
+#ifdef HAVE_TIFF
+bool TiffEncoder::writeLibTiff( const Mat& img, const vector<int>& /*params*/)
+{
+ int channels = img.channels();
+ int width = img.cols, height = img.rows;
+ int depth = img.depth();
+
+ int bitsPerChannel = -1;
+ switch (depth)
+ {
+ case CV_8U:
+ {
+ bitsPerChannel = 8;
+ break;
+ }
+ case CV_16U:
+ {
+ bitsPerChannel = 16;
+ break;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+
+ const int bitsPerByte = 8;
+ size_t fileStep = (width * channels * bitsPerChannel) / bitsPerByte;
+ int rowsPerStrip = (1 << 13)/fileStep;
+
+ if( rowsPerStrip < 1 )
+ rowsPerStrip = 1;
+
+ if( rowsPerStrip > height )
+ rowsPerStrip = height;
+
+
+ // do NOT put "wb" as the mode, because the b means "big endian" mode, not "binary" mode.
+ // http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
+ TIFF* pTiffHandle = TIFFOpen(m_filename.c_str(), "w");
+ if (!pTiffHandle)
+ {
+ return false;
+ }
+
+ // defaults for now, maybe base them on params in the future
+ int compression = COMPRESSION_LZW;
+ int predictor = PREDICTOR_HORIZONTAL;
+
+ int colorspace = channels > 1 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
+
+ if ( !TIFFSetField(pTiffHandle, TIFFTAG_IMAGEWIDTH, width)
+ || !TIFFSetField(pTiffHandle, TIFFTAG_IMAGELENGTH, height)
+ || !TIFFSetField(pTiffHandle, TIFFTAG_BITSPERSAMPLE, bitsPerChannel)
+ || !TIFFSetField(pTiffHandle, TIFFTAG_COMPRESSION, compression)
+ || !TIFFSetField(pTiffHandle, TIFFTAG_PHOTOMETRIC, colorspace)
+ || !TIFFSetField(pTiffHandle, TIFFTAG_SAMPLESPERPIXEL, channels)
+ || !TIFFSetField(pTiffHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)
+ || !TIFFSetField(pTiffHandle, TIFFTAG_ROWSPERSTRIP, rowsPerStrip)
+ || !TIFFSetField(pTiffHandle, TIFFTAG_PREDICTOR, predictor)
+ )
+ {
+ TIFFClose(pTiffHandle);
+ return false;
+ }
+
+ // row buffer, because TIFFWriteScanline modifies the original data!
+ size_t scanlineSize = TIFFScanlineSize(pTiffHandle);
+ AutoBuffer<uchar,1024> _buffer(scanlineSize+32);
+ uchar* buffer = _buffer;
+ if (!buffer)
+ {
+ TIFFClose(pTiffHandle);
+ return false;
+ }
+
+ for (int y = 0; y < height; ++y)
+ {
+ switch(channels)
+ {
+ case 1:
+ {
+ memcpy(buffer, img.data + img.step * y, scanlineSize);
+ break;
+ }
+
+ case 3:
+ {
+ 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) );
+ break;
+ }
+
+ case 4:
+ {
+ 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) );
+ }
+
+ default:
+ {
+ TIFFClose(pTiffHandle);
+ return false;
+ }
+ }
+
+ int writeResult = TIFFWriteScanline(pTiffHandle, buffer, y, 0);
+ if (writeResult != 1)
+ {
+ TIFFClose(pTiffHandle);
+ return false;
+ }
+ }
+
+ TIFFClose(pTiffHandle);
+ return true;
+}
-bool TiffEncoder::write( const Mat& img, const vector<int>& )
+#endif
+
+#ifdef HAVE_TIFF
+bool TiffEncoder::write( const Mat& img, const vector<int>& params)
+#else
+bool TiffEncoder::write( const Mat& img, const vector<int>& /*params*/)
+#endif
{
int channels = img.channels();
int width = img.cols, height = img.rows;
if( !strm.open(*m_buf) )
return false;
}
- else if( !strm.open(m_filename) )
- return false;
+ else
+ {
+#ifdef HAVE_TIFF
+ return writeLibTiff(img, params);
+#else
+ if( !strm.open(m_filename) )
+ return false;
+#endif
+ }
int rowsPerStrip = (1 << 13)/fileStep;
for( ; y < limit; y++ )
{
if( channels == 3 )
+ {
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 )
+ {
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 );
}