tiffr.cpp
// This library is distributed under the conditions of the GNU LGPL.
#include "config.h"
#ifdef HAVE_LIBTIFF
#include <tiffio.h>
#include <qimage.h>
#include <qfile.h>
#include <kdelibs_export.h>
#include <assert.h>
#include "tiffr.h"
static tsize_t tiff_read( thandle_t handle, tdata_t buf, tsize_t size )
{
QIODevice *dev = reinterpret_cast<QIODevice *>( handle );
return dev->readBlock( reinterpret_cast<char *>( buf ), size );
}
static tsize_t tiff_write( thandle_t, tdata_t, tsize_t )
{
return 0;
}
static toff_t tiff_seek( thandle_t handle, toff_t off, int whence )
{
QIODevice *dev = reinterpret_cast<QIODevice *>( handle );
if ( whence == SEEK_CUR )
off += dev->at();
else if ( whence == SEEK_END )
off += dev->size();
if ( !dev->at( off ) )
return ( toff_t )-1;
return dev->at();
}
static toff_t tiff_size( thandle_t handle )
{
QIODevice *dev = reinterpret_cast<QIODevice *>( handle );
return dev->size();
}
static int tiff_close( thandle_t )
{
return 0;
}
static int tiff_map( thandle_t, tdata_t *, toff_t * )
{
return 0;
}
static void tiff_unmap( thandle_t, tdata_t, toff_t )
{
}
KDE_EXPORT void kimgio_tiff_read( QImageIO *io )
{
TIFF *tiff;
uint32 width, height;
uint32 *data;
// FIXME: use qdatastream
// open file
tiff = TIFFClientOpen( QFile::encodeName( io->fileName() ), "r",
( thandle_t )io->ioDevice(),
tiff_read, tiff_write, tiff_seek, tiff_close,
tiff_size, tiff_map, tiff_unmap );
if( tiff == 0 ) {
return;
}
// create image with loaded dimensions
if( TIFFGetField( tiff, TIFFTAG_IMAGEWIDTH, &width ) != 1
|| TIFFGetField( tiff, TIFFTAG_IMAGELENGTH, &height ) != 1 )
return;
QImage image( width, height, 32 );
if( image.isNull()) {
TIFFClose( tiff );
return;
}
data = (uint32 *)image.bits();
//Sven: changed to %ld for 64bit machines
//debug( "unsigned size: %ld, uint32 size: %ld",
// (long)sizeof(unsigned), (long)sizeof(uint32) );
// read data
bool stat =TIFFReadRGBAImage( tiff, width, height, data );
if( stat == 0 ) {
TIFFClose( tiff );
return;
}
// reverse red and blue
for( unsigned i = 0; i < width * height; ++i )
{
uint32 red = ( 0x00FF0000 & data[i] ) >> 16;
uint32 blue = ( 0x000000FF & data[i] ) << 16;
data[i] &= 0xFF00FF00;
data[i] += red + blue;
}
// reverse image (it's upside down)
for( unsigned ctr = 0; ctr < (height>>1); ) {
unsigned *line1 = (unsigned *)image.scanLine( ctr );
unsigned *line2 = (unsigned *)image.scanLine( height
- ( ++ctr ) );
for( unsigned x = 0; x < width; x++ ) {
int temp = *line1;
*line1 = *line2;
*line2 = temp;
line1++;
line2++;
}
// swap rows
}
// set channel order to Qt order
// FIXME: Right now they are the same, but will it change?
// for( int ctr = (image.numBytes() / sizeof(uint32))+1; ctr ; ctr-- ) {
// // TODO: manage alpha with TIFFGetA
// *data = qRgb( TIFFGetR( *data ),
// TIFFGetG( *data ), TIFFGetB( *data ) );
// data++;
// }
TIFFClose( tiff );
io->setImage( image );
io->setStatus ( 0 );
}
KDE_EXPORT void kimgio_tiff_write( QImageIO * )
{
// TODO: stub
}
#endif

KDE Home | KDE Accessibility Home | Description of Access Keys