tiffr.cpp
00001 // This library is distributed under the conditions of the GNU LGPL. 00002 00003 #include "config.h" 00004 00005 #ifdef HAVE_LIBTIFF 00006 00007 #include <tiffio.h> 00008 00009 #include <tqimage.h> 00010 #include <tqfile.h> 00011 #include <tdelibs_export.h> 00012 00013 #include <assert.h> 00014 00015 #include "tiffr.h" 00016 00017 static tsize_t tiff_read( thandle_t handle, tdata_t buf, tsize_t size ) 00018 { 00019 TQIODevice *dev = reinterpret_cast<TQIODevice *>( handle ); 00020 return dev->readBlock( reinterpret_cast<char *>( buf ), size ); 00021 } 00022 00023 static tsize_t tiff_write( thandle_t, tdata_t, tsize_t ) 00024 { 00025 return 0; 00026 } 00027 00028 static toff_t tiff_seek( thandle_t handle, toff_t off, int whence ) 00029 { 00030 TQIODevice *dev = reinterpret_cast<TQIODevice *>( handle ); 00031 00032 if ( whence == SEEK_CUR ) 00033 off += dev->at(); 00034 else if ( whence == SEEK_END ) 00035 off += dev->size(); 00036 00037 if ( !dev->at( off ) ) 00038 return ( toff_t )-1; 00039 00040 return dev->at(); 00041 } 00042 00043 static toff_t tiff_size( thandle_t handle ) 00044 { 00045 TQIODevice *dev = reinterpret_cast<TQIODevice *>( handle ); 00046 return dev->size(); 00047 } 00048 00049 static int tiff_close( thandle_t ) 00050 { 00051 return 0; 00052 } 00053 00054 static int tiff_map( thandle_t, tdata_t *, toff_t * ) 00055 { 00056 return 0; 00057 } 00058 00059 static void tiff_unmap( thandle_t, tdata_t, toff_t ) 00060 { 00061 } 00062 00063 KDE_EXPORT void kimgio_tiff_read( TQImageIO *io ) 00064 { 00065 TIFF *tiff; 00066 uint32 width, height; 00067 uint32 *data; 00068 00069 // FIXME: use qdatastream 00070 00071 // open file 00072 tiff = TIFFClientOpen( TQFile::encodeName( io->fileName() ), "r", 00073 ( thandle_t )io->ioDevice(), 00074 tiff_read, tiff_write, tiff_seek, tiff_close, 00075 tiff_size, tiff_map, tiff_unmap ); 00076 00077 if( tiff == 0 ) { 00078 return; 00079 } 00080 00081 // create image with loaded dimensions 00082 if( TIFFGetField( tiff, TIFFTAG_IMAGEWIDTH, &width ) != 1 00083 || TIFFGetField( tiff, TIFFTAG_IMAGELENGTH, &height ) != 1 ) 00084 return; 00085 00086 TQImage image( width, height, 32 ); 00087 if( image.isNull()) { 00088 TIFFClose( tiff ); 00089 return; 00090 } 00091 data = (uint32 *)image.bits(); 00092 00093 //Sven: changed to %ld for 64bit machines 00094 //debug( "unsigned size: %ld, uint32 size: %ld", 00095 // (long)sizeof(unsigned), (long)sizeof(uint32) ); 00096 00097 // read data 00098 bool stat =TIFFReadRGBAImage( tiff, width, height, data ); 00099 00100 if( stat == 0 ) { 00101 TIFFClose( tiff ); 00102 return; 00103 } 00104 00105 // reverse red and blue 00106 for( unsigned i = 0; i < width * height; ++i ) 00107 { 00108 uint32 red = ( 0x00FF0000 & data[i] ) >> 16; 00109 uint32 blue = ( 0x000000FF & data[i] ) << 16; 00110 data[i] &= 0xFF00FF00; 00111 data[i] += red + blue; 00112 } 00113 00114 // reverse image (it's upside down) 00115 for( unsigned ctr = 0; ctr < (height>>1); ) { 00116 unsigned *line1 = (unsigned *)image.scanLine( ctr ); 00117 unsigned *line2 = (unsigned *)image.scanLine( height 00118 - ( ++ctr ) ); 00119 00120 for( unsigned x = 0; x < width; x++ ) { 00121 int temp = *line1; 00122 *line1 = *line2; 00123 *line2 = temp; 00124 line1++; 00125 line2++; 00126 } 00127 00128 // swap rows 00129 } 00130 00131 // set channel order to Qt order 00132 // FIXME: Right now they are the same, but will it change? 00133 00134 // for( int ctr = (image.numBytes() / sizeof(uint32))+1; ctr ; ctr-- ) { 00135 // // TODO: manage alpha with TIFFGetA 00136 // *data = tqRgb( TIFFGetR( *data ), 00137 // TIFFGetG( *data ), TIFFGetB( *data ) ); 00138 // data++; 00139 // } 00140 TIFFClose( tiff ); 00141 00142 io->setImage( image ); 00143 io->setStatus ( 0 ); 00144 } 00145 00146 KDE_EXPORT void kimgio_tiff_write( TQImageIO * ) 00147 { 00148 // TODO: stub 00149 } 00150 00151 #endif