added 16-bit tiff support, enabled LZW codec in tiff (tickets #588, #590)
authorVadim Pisarevsky <no@email>
Sun, 21 Nov 2010 21:50:45 +0000 (21:50 +0000)
committerVadim Pisarevsky <no@email>
Sun, 21 Nov 2010 21:50:45 +0000 (21:50 +0000)
3rdparty/zlib/zutil.c
modules/highgui/src/grfmt_pxm.cpp
modules/highgui/src/grfmt_tiff.cpp
modules/highgui/src/utils.cpp
modules/highgui/src/utils.hpp

index 898ed34..a7443a5 100644 (file)
@@ -115,7 +115,7 @@ uLong ZEXPORT zlibCompileFlags()
 #ifdef DEBUG
 
 #  ifndef verbose
-#    define verbose 0
+#    define verbose -1
 #  endif
 int ZLIB_INTERNAL z_verbose = verbose;
 
index 015f6d5..33837b1 100644 (file)
@@ -324,7 +324,7 @@ bool  PxMDecoder::readData( Mat& img )
                     else if( img.depth() == CV_8U )
                         icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1), 2 );
                     else
-                        icvCvt_BGR2Gray_16u_C3C1R( (ushort *)src, 0, (ushort *)data, 0, cvSize(m_width,1), 2 );
+                        icvCvt_BGRA2Gray_16u_CnC1R( (ushort *)src, 0, (ushort *)data, 0, cvSize(m_width,1), 3, 2 );
                 }
             }
             result = true;
index 357f83b..6ede59f 100644 (file)
@@ -122,15 +122,19 @@ bool TiffDecoder::readHeader()
         if( TIFFRGBAImageOK( tif, errmsg ) &&
             TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &width ) &&
             TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &height ) &&
-            TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ) &&
-            (!TIFFGetField( tif, TIFFTAG_COMPRESSION, &compression ) ||
-            (compression != COMPRESSION_LZW &&
-             compression != COMPRESSION_OJPEG)))
+            TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ))
         {
+            int bpp=8, ncn = photometric > 1 ? 3 : 1;
+            TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
+            TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
+            
             m_width = width;
             m_height = height;
-            m_type = photometric > 1 ? CV_8UC3 : CV_8UC1;
-
+            if( bpp > 8 &&
+               ((photometric != 2 && photometric != 1) ||
+                (ncn != 1 && ncn != 3 && ncn != 4)))
+                bpp = 8;
+            m_type = CV_MAKETYPE(bpp > 8 ? CV_16U : CV_8U, photometric > 1 ? 3 : 1);
             result = true;
         }
     }
@@ -148,6 +152,9 @@ bool  TiffDecoder::readData( Mat& img )
     bool color = img.channels() > 1;
     uchar* data = img.data;
     int step = (int)img.step;
+    
+    if( img.depth() != CV_8U && img.depth() != CV_16U )
+        return false;
 
     if( m_tif && m_width && m_height )
     {
@@ -155,6 +162,12 @@ bool  TiffDecoder::readData( Mat& img )
         int tile_width0 = m_width, tile_height0 = 0;
         int x, y, i;
         int is_tiled = TIFFIsTiled(tif);
+        int photometric;
+        TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric );
+        int bpp = 8, ncn = photometric > 1 ? 3 : 1;
+        TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
+        TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
+        int dst_bpp = img.depth() == CV_8U ? 8 : 16;
 
         if( (!is_tiled &&
             TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 )) ||
@@ -168,8 +181,10 @@ bool  TiffDecoder::readData( Mat& img )
             if( tile_height0 <= 0 )
                 tile_height0 = m_height;
 
-            AutoBuffer<uchar> _buffer(tile_height0*tile_width0*4);
+            AutoBuffer<uchar> _buffer(tile_height0*tile_width0*8);
             uchar* buffer = _buffer;
+            ushort* buffer16 = (ushort*)buffer;
+            int tileidx = 0;
 
             for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 )
             {
@@ -178,33 +193,89 @@ bool  TiffDecoder::readData( Mat& img )
                 if( y + tile_height > m_height )
                     tile_height = m_height - y;
 
-                for( x = 0; x < m_width; x += tile_width0 )
+                for( x = 0; x < m_width; x += tile_width0, tileidx++ )
                 {
                     int tile_width = tile_width0, ok;
 
                     if( x + tile_width > m_width )
                         tile_width = m_width - x;
 
-                    if( !is_tiled )
-                        ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer );
-                    else
-                        ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer );
-
-                    if( !ok )
+                    if( dst_bpp == 8 )
                     {
-                        close();
-                        return false;
+                        if( !is_tiled )
+                            ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer );
+                        else
+                            ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer );
+                        
+                        if( !ok )
+                        {
+                            close();
+                            return false;
+                        }
+                        
+                        for( i = 0; i < tile_height; i++ )
+                            if( color )
+                                icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0,
+                                                         data + x*3 + step*(tile_height - i - 1), 0,
+                                                         cvSize(tile_width,1), 2 );
+                            else
+                                icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0,
+                                                          data + x + step*(tile_height - i - 1), 0,
+                                                          cvSize(tile_width,1), 2 );
                     }
-
-                    for( i = 0; i < tile_height; i++ )
-                        if( color )
-                            icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0,
-                                          data + x*3 + step*(tile_height - i - 1), 0,
-                                          cvSize(tile_width,1), 2 );
+                    else
+                    {
+                        if( !is_tiled )
+                            ok = TIFFReadEncodedStrip( tif, tileidx, (uint32*)buffer, -1 );
                         else
-                            icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0,
-                                           data + x + step*(tile_height - i - 1), 0,
-                                           cvSize(tile_width,1), 2 );
+                            ok = TIFFReadEncodedTile( tif, tileidx, (uint32*)buffer, -1 );
+                        
+                        if( !ok )
+                        {
+                            close();
+                            return false;
+                        }
+                        
+                        for( i = 0; i < tile_height; i++ )
+                        {
+                            if( color )
+                            {
+                                if( ncn == 1 )
+                                {
+                                    icvCvt_Gray2BGR_16u_C1C3R(buffer16 + i*tile_width*ncn, 0,
+                                                              (ushort*)(data + step*i) + x*3, 0,
+                                                              cvSize(tile_width,1) );
+                                }
+                                else if( ncn == 3 )
+                                {
+                                    icvCvt_RGB2BGR_16u_C3R(buffer16 + i*tile_width*ncn, 0,
+                                                           (ushort*)(data + step*i) + x*3, 0,
+                                                           cvSize(tile_width,1) );
+                                }
+                                else
+                                {
+                                    icvCvt_BGRA2BGR_16u_C4C3R(buffer16 + i*tile_width*ncn, 0,
+                                                           (ushort*)(data + step*i) + x*3, 0,
+                                                           cvSize(tile_width,1), 2 );
+                                }
+                            }
+                            else
+                            {
+                                if( ncn == 1 )
+                                {
+                                    memcpy((ushort*)(data + step*i)+x,
+                                           buffer16 + i*tile_width*ncn,
+                                           tile_width*sizeof(buffer16[0]));
+                                }
+                                else
+                                {
+                                    icvCvt_BGRA2Gray_16u_CnC1R(buffer16 + i*tile_width*ncn, 0,
+                                                           (ushort*)(data + step*i) + x, 0,
+                                                           cvSize(tile_width,1), ncn, 2 );
+                                }
+                            }
+                        }
+                    } 
                 }
             }
 
index 8f479ed..9c20065 100644 (file)
@@ -66,21 +66,21 @@ void icvCvt_BGR2Gray_8u_C3C1R( const uchar* rgb, int rgb_step,
 }
 
 
-void icvCvt_BGR2Gray_16u_C3C1R( const ushort* rgb, int rgb_step,
+void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* rgb, int rgb_step,
                                 ushort* gray, int gray_step,
-                                CvSize size, int _swap_rb )
+                                CvSize size, int ncn, int _swap_rb )
 {
     int i;
     int swap_rb = _swap_rb ? 2 : 0;
     for( ; size.height--; gray += gray_step )
     {
-        for( i = 0; i < size.width; i++, rgb += 3 )
+        for( i = 0; i < size.width; i++, rgb += ncn )
         {
             int t = descale( rgb[swap_rb]*cB + rgb[1]*cG + rgb[swap_rb^2]*cR, SCALE );
             gray[i] = (ushort)t;
         }
 
-        rgb += rgb_step - size.width*3;
+        rgb += rgb_step - size.width*ncn;
     }
 }
 
@@ -119,6 +119,21 @@ void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step,
 }
 
 
+void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step,
+                              ushort* bgr, int bgr_step, CvSize size )
+{
+    int i;
+    for( ; size.height--; gray += gray_step/sizeof(gray[0]) )
+    {
+        for( i = 0; i < size.width; i++, bgr += 3 )
+        {
+            bgr[0] = bgr[1] = bgr[2] = gray[i];
+        }
+        bgr += bgr_step/sizeof(bgr[0]) - size.width*3;
+    }
+}
+
+
 void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step,
                                uchar* bgr, int bgr_step,
                                CvSize size, int _swap_rb )
@@ -139,6 +154,26 @@ void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step,
 }
 
 
+void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step,
+                              ushort* bgr, int bgr_step,
+                              CvSize size, int _swap_rb )
+{
+    int i;
+    int swap_rb = _swap_rb ? 2 : 0;
+    for( ; size.height--; )
+    {
+        for( i = 0; i < size.width; i++, bgr += 3, bgra += 4 )
+        {
+            uchar t0 = bgra[swap_rb], t1 = bgra[1];
+            bgr[0] = t0; bgr[1] = t1;
+            t0 = bgra[swap_rb^2]; bgr[2] = t0;
+        }
+        bgr += bgr_step/sizeof(bgr[0]) - size.width*3;
+        bgra += bgra_step/sizeof(bgra[0]) - size.width*4;
+    }
+}
+
+
 void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step,
                               uchar* rgba, int rgba_step, CvSize size )
 {
index 1e81c17..5eba19a 100644 (file)
@@ -55,20 +55,28 @@ struct PaletteEntry
 #define  descale(x,n)  (((x) + (1 << ((n)-1))) >> (n))
 #define  saturate(x)   (uchar)(((x) & ~255) == 0 ? (x) : ~((x)>>31))
 
-void icvCvt_BGR2Gray_16u_C3C1R( const ushort* bgr, int bgr_step,
-                                ushort* gray, int gray_step,
-                                CvSize size, int swap_rb=0 );
 void icvCvt_BGR2Gray_8u_C3C1R( const uchar* bgr, int bgr_step,
                                uchar* gray, int gray_step,
                                CvSize size, int swap_rb=0 );
 void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* bgra, int bgra_step,
                                 uchar* gray, int gray_step,
                                 CvSize size, int swap_rb=0 );
+void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* bgra, int bgra_step,
+                               ushort* gray, int gray_step,
+                               CvSize size, int ncn, int swap_rb=0 );
+
 void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step,
                                uchar* bgr, int bgr_step, CvSize size );
+void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step,
+                               ushort* bgr, int bgr_step, CvSize size );
+
 void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step,
                                uchar* bgr, int bgr_step,
                                CvSize size, int swap_rb=0 );
+void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step,
+                               ushort* bgr, int bgr_step,
+                               CvSize size, int _swap_rb );
+
 void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step,
                             uchar* rgb, int rgb_step, CvSize size );
 #define icvCvt_RGB2BGR_8u_C3R icvCvt_BGR2RGB_8u_C3R