added 16-bit support to TiffEncoder (restore after #4919)
authorVladislav Vinogradov <no@email>
Mon, 25 Apr 2011 10:46:06 +0000 (10:46 +0000)
committerVladislav Vinogradov <no@email>
Mon, 25 Apr 2011 10:46:06 +0000 (10:46 +0000)
modules/highgui/src/grfmt_tiff.cpp
modules/highgui/src/grfmt_tiff.hpp
modules/highgui/src/utils.cpp
modules/highgui/src/utils.hpp

index dfb4db2..1839a6e 100644 (file)
@@ -306,6 +306,11 @@ ImageEncoder TiffEncoder::newEncoder() const
     return new TiffEncoder;
 }
 
+bool TiffEncoder::isFormatSupported( int depth ) const
+{
+    return depth == CV_8U || depth == CV_16U;
+}
+
 void  TiffEncoder::writeTag( WLByteStream& strm, TiffTag tag,
                              TiffFieldType fieldType,
                              int count, int value )
@@ -321,7 +326,14 @@ bool  TiffEncoder::write( const Mat& img, const vector<int>& )
 {
     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 +368,7 @@ bool  TiffEncoder::write( const Mat& img, const vector<int>& )
     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 +388,15 @@ bool  TiffEncoder::write( const Mat& img, const vector<int>& )
         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 +434,13 @@ bool  TiffEncoder::write( const Mat& img, const vector<int>& )
 
     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();
index 877c229..037739a 100644 (file)
@@ -118,6 +118,8 @@ public:
     TiffEncoder();
     virtual ~TiffEncoder();
 
+    bool isFormatSupported( int depth ) const;
+
     bool  write( const Mat& img, const vector<int>& params );
     ImageEncoder newEncoder() const;
 
index 4197b90..095a256 100644 (file)
@@ -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 )
index 5eba19a..d4b264e 100644 (file)
@@ -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,