diff options
Diffstat (limited to 'kooka/kookaimage.cpp')
-rw-r--r-- | kooka/kookaimage.cpp | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/kooka/kookaimage.cpp b/kooka/kookaimage.cpp new file mode 100644 index 00000000..4db87728 --- /dev/null +++ b/kooka/kookaimage.cpp @@ -0,0 +1,413 @@ +/*************************************************************************** + kookaimage.cpp - Kooka's Image + ------------------- + begin : Thu Nov 20 2001 + copyright : (C) 1999 by Klaas Freitag + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This file may be distributed and/or modified under the terms of the * + * GNU General Public License version 2 as published by the Free Software * + * Foundation and appearing in the file COPYING included in the * + * packaging of this file. * + * + * As a special exception, permission is given to link this program * + * with any version of the KADMOS ocr/icr engine of reRecognition GmbH, * + * Kreuzlingen and distribute the resulting executable without * + * including the source code for KADMOS in the source distribution. * + * + * As a special exception, permission is given to link this program * + * with any edition of Qt, and distribute the resulting executable, * + * without including the source code for Qt in the source distribution. * + * * + ***************************************************************************/ + +#include <kdebug.h> +#include <kurl.h> +#include <kfileitem.h> + +#include "kookaimage.h" +#include "config.h" +#ifdef HAVE_LIBTIFF +#include <tiffio.h> +#include <tiff.h> +#endif +/** + *@author Klaas Freitag + */ + + +KookaImage::KookaImage( ) + : QImage(), + m_subImages(-1), + m_subNo(0), + m_parent(0), + m_fileBound(false), + m_tileCols(0) +{ + +} + +/* constructor for subimages */ +KookaImage::KookaImage( int subNo, KookaImage *p ) + : QImage(), + m_subImages(-1), + m_subNo(subNo), + m_parent( p ), + m_fileItem(0L), + m_fileBound(false), + m_tileCols(0) +{ + kdDebug(28000) << "Setting subimageNo to " << subNo << endl; +} + +KookaImage& KookaImage::operator=(const KookaImage& img) +{ + QImage::operator=(img); + + m_subImages = img.subImagesCount(); + m_subNo = img.m_subNo; + m_parent = img.m_parent; + m_url = img.m_url; + m_fileItem = img.m_fileItem; + + return *this; +} + +KookaImage& KookaImage::operator=(const QImage& img) +{ + QImage::operator=(img); + return *this; +} + +KFileItem* KookaImage::fileItem() const +{ + return m_fileItem; +} + +void KookaImage::setFileItem( KFileItem* it ) +{ + m_fileItem = it; +} + +const KFileMetaInfo KookaImage::fileMetaInfo( ) +{ + QString filename = localFileName( ); + if( ! filename.isEmpty() ) + { + kdDebug(28000) << "Fetching metainfo for " << filename << endl; + const KFileMetaInfo info( filename ); + return info; + } + else + return KFileMetaInfo(); +} + +QString KookaImage::localFileName( ) const +{ + + if( ! m_url.isEmpty() ) + return( m_url.directory() + "/" + m_url.fileName()); + else + return QString(); +} + +bool KookaImage::loadFromUrl( const KURL& url ) +{ + bool ret = true; + m_url = url; + QString filename = localFileName( ); + QString format ( imageFormat( filename )); + + /* if the format was not recogniseable, check the extension, if it is tif, try to read it by + * tifflib */ + if( format.isNull() ) + { + if( filename.endsWith( "tif" ) || filename.endsWith( "tiff" ) || + filename.endsWith( "TIF" ) || filename.endsWith( "TIFF" ) ) + { + format = "tif"; + kdDebug(28000) << "Setting format to tif by extension" << endl; + } + } + + kdDebug(28000) << "Image format to load: <" << format << "> from file <" << filename << ">" << endl; + bool haveTiff = false; + + if( !m_url.isLocalFile() ) + { + kdDebug(28000)<<"ERROR: Can not laod non-local images -> not yet implemented!" << endl; + return false; + } + +#ifdef HAVE_LIBTIFF + TIFF* tif = 0; + m_subImages = 0; + + if( format == "tif" || + format == "TIF" || + format == "TIFF" || + format == "tiff" ) + { + /* if it is tiff, check with Tifflib if it is multiple sided */ + kdDebug(28000) << "Trying to load TIFF!" << endl; + tif = TIFFOpen(filename.latin1(), "r"); + if (tif) + { + do { + m_subImages++; + } while (TIFFReadDirectory(tif)); + kdDebug(28000) << m_subImages << " TIFF-directories found" << endl; + + haveTiff = true; + } + } +#endif + if( !haveTiff ) + { + /* Qt can only read one image */ + ret = load(filename); + if( ret ) + { + m_subImages = 0; + m_subNo = 0; + } + } +#ifdef HAVE_LIBTIFF + else + { + loadTiffDir( filename, 0); + /* its a tiff, read by tifflib directly */ + // Find the width and height of the image + } +#endif + + m_fileBound = ret; + return( ret ); +} + + +KookaImage::KookaImage( const QImage& img ) + : QImage( img ) + /* m_subImages( 1 ) */ +{ + m_subImages = 0; + + /* Load one QImage, can not be Tiff yet. */ + kdDebug(28000) << "constructor from other image here " << endl; +} + + +/* loads the number stored in m_subNo */ +void KookaImage::extractNow() +{ + kdDebug(28000) << "extracting a subimage number " << m_subNo << endl; + + KookaImage *parent = parentImage(); + + if( parent ) + { + loadTiffDir( parent->localFileName(), m_subNo ); + } + else + { + kdDebug(28000) << "ERR: No parent defined - can not laod subimage" << endl; + } +} + +KURL KookaImage::url() const +{ + return m_url; +} + +bool KookaImage::loadTiffDir( const QString& filename, int no ) +{ +#ifdef HAVE_LIBTIFF + int imgWidth, imgHeight; + TIFF* tif = 0; + /* if it is tiff, check with Tifflib if it is multiple sided */ + kdDebug(28000) << "Trying to load TIFF, subimage number "<< no << endl; + tif = TIFFOpen(filename.latin1(), "r"); + if (!tif) + return false; + + if( ! TIFFSetDirectory( tif, no ) ) + { + kdDebug(28000) << "ERR: could not set Directory " << no << endl; + TIFFClose(tif); + return false; + } + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imgWidth); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imgHeight); + + + /* TODO: load bw-image correctly only 2 bit */ + // KookaImage tmpImg; + create( imgWidth, imgHeight, 32 ); + if (TIFFReadRGBAImage(tif, imgWidth, imgHeight, (uint32*) bits(),0)) + { + // successfully read. now convert. + // reverse red and blue + uint32 *data; + data = (uint32 *)bits(); + for( unsigned i = 0; i < unsigned(imgWidth * imgHeight); ++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) + unsigned h = unsigned(imgHeight); + for( unsigned ctr = 0; ctr < h>>1; ) + { + unsigned *line1 = (unsigned *)scanLine( ctr ); + unsigned *line2 = (unsigned *)scanLine( imgHeight + - ( ++ctr ) ); + + unsigned w = unsigned(imgWidth); + for( unsigned x = 0; x < w; x++ ) + { + int temp = *line1; + *line1 = *line2; + *line2 = temp; + line1++; + line2++; + } + } + } + + /* fetch the x- and y-resolutions to adjust images */ + float xReso, yReso; + bool resosFound; + resosFound = TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xReso ); + resosFound &= TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yReso ); + kdDebug(28000)<< "Tiff image: X-Resol.: " << xReso << " and Y-Resol.: " << yReso << endl; + + TIFFClose(tif); + + /* Check now if resolution in x- and y-direction differ. If so, stretch the image + * accordingly. + */ + if( resosFound && xReso != yReso ) + { + if( xReso > yReso ) + { + float yScalefactor = xReso / yReso; + kdDebug(28000) << "Different resolution x/y, rescaling with factor " << yScalefactor << endl; + /* rescale the image */ + *this = smoothScale( imgWidth, int(imgHeight*yScalefactor), QImage::ScaleFree ); + } + else + { + /* yReso > xReso */ + float scalefactor = yReso / xReso; + kdDebug(28000) << "Different resolution x/y, rescaling x with factor " << scalefactor << endl; + /* rescale the image */ + *this = smoothScale( int(imgWidth*scalefactor), imgHeight, QImage::ScaleFree ); + + } + } + +#endif + return true; +} + + +int KookaImage::subImagesCount() const +{ + return( m_subImages ); +} + +KookaImage::~KookaImage() +{ + +} + +KookaImage* KookaImage::parentImage() const +{ + return( m_parent ); +} + +bool KookaImage::isSubImage() const +{ + return( subImagesCount() ); +} + +/* + * tiling + */ +int KookaImage::cutToTiles( const QSize maxSize, int& rows, int& cols, TileMode ) +{ + QSize imgSize = size(); + + int w = imgSize.width(); + if( w > maxSize.width() ) + { + // image is wider than paper + w = maxSize.width(); + } + int h = imgSize.height(); + if( h > maxSize.height() ) + { + // image is wider than paper + h = maxSize.height(); + } + + int absX = 0; // absolute x position from where to start print + int absY = 0; // on the image, left top corner of the part to print + rows = 0; + + while( h ) // Loop over height, cut in vertical direction + { + rows++; + cols = 0; + while( w ) // Loop over width, cut in horizontal direction + { + cols++; + m_tileVector.append( QRect( absX, absY, w, h )); + + absX += w+1; + w = imgSize.width() - absX; + + // if w < 0, this was the last loop, set w to zero to stop loop + if( w < 0 ) w = 0; + + // if > 0 here, a new page is required + if( w > 0 ) + { + if( w > maxSize.width() ) w = maxSize.width(); + } + } + // Reset the X-values to start on the left border again + absX = 0; + // start with full width again + w = imgSize.width(); + if( w > maxSize.width() ) + w = maxSize.width(); + + absY += h+1; + h = imgSize.height() - absY; + + if( h < 0 ) h = 0; // be sure to meet the break condition + if( h > maxSize.height()) h = maxSize.height(); // limit to page height + } + m_tileCols = cols; + + return m_tileVector.count(); +} + + + +QRect KookaImage::getTileRect( int rowPos, int colPos ) const +{ + int indx = rowPos*m_tileCols+colPos; + kdDebug(28000) << "Tile Index: " << indx << endl; + const QRect r = m_tileVector[(rowPos)*m_tileCols + colPos]; + + return r; +} |