summaryrefslogtreecommitdiffstats
path: root/filters/chalk/tiff/kis_tiff_converter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'filters/chalk/tiff/kis_tiff_converter.cpp')
-rw-r--r--filters/chalk/tiff/kis_tiff_converter.cpp677
1 files changed, 677 insertions, 0 deletions
diff --git a/filters/chalk/tiff/kis_tiff_converter.cpp b/filters/chalk/tiff/kis_tiff_converter.cpp
new file mode 100644
index 000000000..ea39dec28
--- /dev/null
+++ b/filters/chalk/tiff/kis_tiff_converter.cpp
@@ -0,0 +1,677 @@
+/*
+ * Copyright (c) 2005-2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_tiff_converter.h"
+
+#include <stdio.h>
+
+#include <config.h>
+#include LCMS_HEADER
+
+#include <tqfile.h>
+
+#include <tdeapplication.h>
+#include <KoDocumentInfo.h>
+
+#include <tdeio/netaccess.h>
+
+#include <kis_abstract_colorspace.h>
+#include <kis_colorspace_factory_registry.h>
+#include <kis_doc.h>
+#include <kis_image.h>
+#include <kis_iterators_pixel.h>
+#include <kis_layer.h>
+#include <kis_meta_registry.h>
+#include <kis_profile.h>
+#include <kis_group_layer.h>
+#include <kis_paint_layer.h>
+
+#include "kis_tiff_reader.h"
+#include "kis_tiff_ycbcr_reader.h"
+#include "kis_tiff_stream.h"
+#include "kis_tiff_writer_visitor.h"
+
+namespace {
+
+ TQString getColorSpaceForColorType(uint16 color_type, uint16 color_nb_bits, TIFF *image, uint16 &nbchannels, uint16 &extrasamplescount, uint8 &destDepth, uint16 sampletype) {
+ if(color_type == PHOTOMETRIC_MINISWHITE || color_type == PHOTOMETRIC_MINISBLACK)
+ {
+ if(nbchannels == 0) nbchannels = 1;
+ extrasamplescount = nbchannels - 1; // FIX the extrasamples count in case of
+ if(color_nb_bits <= 8)
+ {
+ destDepth = 8;
+ return "GRAYA";
+ } else {
+ destDepth = 16;
+ return "GRAYA16";
+ }
+ } else if(color_type == PHOTOMETRIC_RGB /*|| color_type == */ ) {
+ if(nbchannels == 0) nbchannels = 3;
+ extrasamplescount = nbchannels - 3; // FIX the extrasamples count in case of
+ if(sampletype == SAMPLEFORMAT_IEEEFP)
+ {
+ if(color_nb_bits == 16)
+ {
+ destDepth = 16;
+ return "RGBAF16HALF";
+ } else if( color_nb_bits == 32) {
+ destDepth = 32;
+ return "RGBAF32";
+ }
+ return "";
+ } else {
+ if(color_nb_bits <= 8)
+ {
+ destDepth = 8;
+ return "RGBA";
+ } else {
+ destDepth = 16;
+ return "RGBA16";
+ }
+ }
+ } else if(color_type == PHOTOMETRIC_YCBCR ) {
+ if(nbchannels == 0) nbchannels = 3;
+ extrasamplescount = nbchannels - 3; // FIX the extrasamples count in case of
+ if(color_nb_bits <= 8)
+ {
+ destDepth = 8;
+ return "YCbCrAU8";
+ } else {
+ destDepth = 16;
+ return "YCbCrAU16";
+ }
+ } else if(color_type == PHOTOMETRIC_SEPARATED ) {
+ if(nbchannels == 0) nbchannels = 4;
+ // SEPARATED is in general CMYK but not allways, so we check
+ uint16 inkset;
+ if((TIFFGetField(image, TIFFTAG_INKSET, &inkset) == 0)){
+ kdDebug(41008) << "Image does not define the inkset." << endl;
+ inkset = 2;
+ }
+ if(inkset != INKSET_CMYK)
+ {
+ kdDebug(41008) << "Unsupported inkset (right now, only CMYK is supported)" << endl;
+ char** ink_names;
+ uint16 numberofinks;
+ if( TIFFGetField(image, TIFFTAG_INKNAMES, &ink_names) && TIFFGetField(image, TIFFTAG_NUMBEROFINKS, &numberofinks) )
+ {
+ kdDebug(41008) << "Inks are : " << endl;
+ for(uint i = 0; i < numberofinks; i++)
+ {
+ kdDebug(41008) << ink_names[i] << endl;
+ }
+ } else {
+ kdDebug(41008) << "inknames aren't defined !" << endl;
+ // To be able to read stupid adobe files, if there are no information about inks and four channels, then it's a CMYK file :
+ if( nbchannels - extrasamplescount != 4)
+ {
+ return "";
+ }
+ }
+ }
+ if(color_nb_bits <= 8)
+ {
+ destDepth = 8;
+ return "CMYK";
+ } else {
+ destDepth = 16;
+ return "CMYKA16";
+ }
+ } else if(color_type == PHOTOMETRIC_CIELAB
+#ifdef PHOTOMETRIC_ICCLAB
+ || color_type == PHOTOMETRIC_ICCLAB
+#endif
+ ) {
+ destDepth = 16;
+ if(nbchannels == 0) nbchannels = 3;
+ extrasamplescount = nbchannels - 3; // FIX the extrasamples count in case of
+ return "LABA"; // TODO add support for a 8bit LAB colorspace when it is written
+ } else if(color_type == PHOTOMETRIC_PALETTE) {
+ destDepth = 16;
+ if(nbchannels == 0) nbchannels = 2;
+ extrasamplescount = nbchannels - 2; // FIX the extrasamples count in case of
+ // <-- we will convert the index image to RGBA16 as the palette is allways on 16bits colors
+ return "RGBA16";
+ }
+ return "";
+ }
+}
+
+KisTIFFConverter::KisTIFFConverter(KisDoc *doc, KisUndoAdapter *adapter)
+{
+ m_doc = doc;
+ m_adapter = adapter;
+ m_job = 0;
+ m_stop = false;
+}
+
+KisTIFFConverter::~KisTIFFConverter()
+{
+}
+
+KisImageBuilder_Result KisTIFFConverter::decode(const KURL& uri)
+{
+ kdDebug(41008) << "Start decoding TIFF File" << endl;
+ // Opent the TIFF file
+ TIFF *image = 0;
+ if((image = TIFFOpen(TQFile::encodeName(uri.path()), "r")) == NULL){
+ kdDebug(41008) << "Could not open the file, either it doesn't exist, either it is not a TIFF : " << uri.path() << endl;
+
+ return (KisImageBuilder_RESULT_BAD_FETCH);
+ }
+ do {
+ kdDebug(41008) << "Read new sub-image" << endl;
+ KisImageBuilder_Result result = readTIFFDirectory(image);
+ if(result != KisImageBuilder_RESULT_OK){
+ return result;
+ }
+ } while (TIFFReadDirectory(image));
+ // Freeing memory
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_OK;
+}
+
+KisImageBuilder_Result KisTIFFConverter::readTIFFDirectory( TIFF* image)
+{
+ // Read information about the tiff
+ uint32 width, height;
+ if(TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width) == 0){
+ kdDebug(41008) << "Image does not define its width" << endl;
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_INVALID_ARG;
+ }
+ if(TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height) == 0){
+ kdDebug(41008) << "Image does not define its height" << endl;
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_INVALID_ARG;
+ }
+ uint16 depth;
+ if((TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &depth) == 0)){
+ kdDebug(41008) << "Image does not define its depth" << endl;
+ depth = 1;
+ }
+ uint16 sampletype;
+ if((TIFFGetField(image, TIFFTAG_SAMPLEFORMAT, &sampletype) == 0)){
+ kdDebug(41008) << "Image does not define its sample type" << endl;
+ sampletype = SAMPLEFORMAT_UINT;
+ }
+ // Determine the number of channels (usefull to know if a file has an alpha or not
+ uint16 nbchannels;
+ if(TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &nbchannels) == 0){
+ kdDebug(41008) << "Image has an undefined number of samples per pixel" << endl;
+ nbchannels = 0;
+ }
+ // Get the number of extrasamples and information about them
+ uint16 *sampleinfo, extrasamplescount;
+ if(TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extrasamplescount, &sampleinfo) == 0)
+ {
+ extrasamplescount = 0;
+ }
+ // Determine the colorspace
+ uint16 color_type;
+ if(TIFFGetField(image, TIFFTAG_PHOTOMETRIC, &color_type) == 0){
+ kdDebug(41008) << "Image has an undefined photometric interpretation" << endl;
+ color_type = PHOTOMETRIC_MINISWHITE;
+ }
+ uint8 dstDepth;
+ TQString csName = getColorSpaceForColorType(color_type, depth, image, nbchannels, extrasamplescount, dstDepth,sampletype);
+ if(csName.isEmpty()) {
+ kdDebug(41008) << "Image has an unsupported colorspace : " << color_type << " for this depth : "<< depth << endl;
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE;
+ }
+ kdDebug(41008) << "Colorspace is : " << csName << " with a depth of " << depth << " and with a nb of channels of " << nbchannels << endl;
+
+ // Read image profile
+ kdDebug() << "Reading profile" << endl;
+ KisProfile* profile = 0;
+ DWORD EmbedLen;
+ LPBYTE EmbedBuffer;
+
+ if (TIFFGetField(image, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer)) {
+ kdDebug(41008) << "Profile found" << endl;
+ TQByteArray rawdata;
+ rawdata.resize(EmbedLen);
+ memcpy(rawdata.data(), EmbedBuffer, EmbedLen);
+ profile = new KisProfile(rawdata);
+ } else {
+ kdDebug(41008) << "No Profile found" << endl;
+ }
+
+ // Retrieve a pointer to the colorspace
+ KisColorSpace* cs = 0;
+ if (profile && profile->isSuitableForOutput())
+ {
+ kdDebug(41008) << "image has embedded profile: " << profile -> productName() << "\n";
+ cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(csName, profile);
+ }
+ else
+ cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName,""),"");
+
+ if(cs == 0) {
+ kdDebug(41008) << "Colorspace " << csName << " is not available, please check your installation." << endl;
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE;
+ }
+
+ // Create the cmsTransform if needed
+ cmsHTRANSFORM transform = 0;
+ if(profile && !profile->isSuitableForOutput())
+ {
+ kdDebug(41008) << "The profile can't be used in chalk, need conversion" << endl;
+ transform = cmsCreateTransform(profile->profile(), cs->colorSpaceType(),
+ cs->getProfile()->profile() , cs->colorSpaceType(),
+ INTENT_PERCEPTUAL, 0);
+ }
+
+
+ // Check if there is an alpha channel
+ int8 alphapos = -1; // <- no alpha
+ // Check which extra is alpha if any
+ kdDebug(41008) << "There are " << nbchannels << " channels and " << extrasamplescount << " extra channels" << endl;
+ if(sampleinfo) // index images don't have any sampleinfo, and therefor sampleinfo == 0
+ {
+ for(int i = 0; i < extrasamplescount; i ++)
+ {
+ kdDebug(41008) << i << " " << extrasamplescount << " " << (cs->nColorChannels()) << nbchannels << " " << sampleinfo[i] << endl;
+ if(sampleinfo[i] == EXTRASAMPLE_ASSOCALPHA)
+ {
+ // XXX: dangelo: the color values are already multiplied with
+ // the alpha value. This needs to be reversed later (postprocessor?)
+ alphapos = i;
+ }
+
+ if (sampleinfo[i] == EXTRASAMPLE_UNASSALPHA)
+ {
+ // color values are not premultiplied with alpha, and can be used as they are.
+ alphapos = i;
+ }
+ }
+ }
+
+ // Read META Information
+ KoDocumentInfo * info = m_doc->documentInfo();
+ KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(info->page( "about" ));
+ KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor *>(info->page( "author"));
+ char* text;
+ if (TIFFGetField(image, TIFFTAG_ARTIST, &text)) {
+ authorPage->setFullName(text);
+ }
+ if (TIFFGetField(image, TIFFTAG_DOCUMENTNAME, &text)) {
+ aboutPage->setTitle(text);
+ }
+ if (TIFFGetField(image,TIFFTAG_IMAGEDESCRIPTION,&text) ) {
+ aboutPage->setAbstract( text );
+ }
+
+
+ // Get the planar configuration
+ uint16 planarconfig;
+ if(TIFFGetField(image, TIFFTAG_PLANARCONFIG, &planarconfig) == 0)
+ {
+ kdDebug(41008) << "Plannar configuration is not define" << endl;
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_INVALID_ARG;
+ }
+ // Creating the KisImageSP
+ if( ! m_img ) {
+ m_img = new KisImage(m_doc->undoAdapter(), width, height, cs, "built image");
+ TQ_CHECK_PTR(m_img);
+ m_img->blockSignals(true); // Don't send out signals while we're building the image
+ if(profile)
+ {
+ m_img -> addAnnotation( profile->annotation() );
+ }
+ } else {
+ if( m_img->width() < (TQ_INT32)width || m_img->height() < (TQ_INT32)height)
+ {
+ TQ_UINT32 newwidth = (m_img->width() < (TQ_INT32)width) ? width : m_img->width();
+ TQ_UINT32 newheight = (m_img->height() < (TQ_INT32)height) ? height : m_img->height();
+ m_img->resize(newwidth, newheight, false);
+ }
+ }
+ KisPaintLayer* layer = new KisPaintLayer(m_img, m_img -> nextLayerName(), TQ_UINT8_MAX);
+ tdata_t buf = 0;
+ tdata_t* ps_buf = 0; // used only for planar configuration seperated
+ TIFFStreamBase* tiffstream;
+
+ KisTIFFReaderBase* tiffReader = 0;
+
+ TQ_UINT8 poses[5];
+ KisTIFFPostProcessor* postprocessor = 0;
+
+ // Configure poses
+ uint8 nbcolorsamples = nbchannels - extrasamplescount;
+ switch(color_type)
+ {
+ case PHOTOMETRIC_MINISWHITE:
+ {
+ poses[0] = 0; poses[1] = 1;
+ postprocessor = new KisTIFFPostProcessorInvert(nbcolorsamples);
+ }
+ break;
+ case PHOTOMETRIC_MINISBLACK:
+ {
+ poses[0] = 0; poses[1] = 1;
+ postprocessor = new KisTIFFPostProcessor(nbcolorsamples);
+ }
+ break;
+ case PHOTOMETRIC_CIELAB:
+ {
+ poses[0] = 0; poses[1] = 1; poses[2] = 2; poses[3] = 3;
+ postprocessor = new KisTIFFPostProcessorICCLABtoCIELAB(nbcolorsamples);
+ }
+ break;
+#ifdef PHOTOMETRIC_ICCLAB
+ case PHOTOMETRIC_ICCLAB:
+ {
+ poses[0] = 0; poses[1] = 1; poses[2] = 2; poses[3] = 3;
+ postprocessor = new KisTIFFPostProcessor(nbcolorsamples);
+ }
+ break;
+#endif
+ case PHOTOMETRIC_RGB:
+ {
+ poses[0] = 2; poses[1] = 1; poses[2] = 0; poses[3] = 3;
+ postprocessor = new KisTIFFPostProcessor(nbcolorsamples);
+ }
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ {
+ poses[0] = 0; poses[1] = 1; poses[2] = 2; poses[3] = 3; poses[4] = 4;
+ postprocessor = new KisTIFFPostProcessor(nbcolorsamples);
+ }
+ break;
+ default:
+ break;
+ }
+
+
+ // Initisalize tiffReader
+ uint16 * lineSizeCoeffs = new uint16[nbchannels];
+ uint16 vsubsampling = 1;
+ uint16 hsubsampling = 1;
+ for(uint i = 0; i < nbchannels; i++)
+ {
+ lineSizeCoeffs[i] = 1;
+ }
+ if( color_type == PHOTOMETRIC_PALETTE)
+ {
+ uint16 *red; // No need to free them they are free by libtiff
+ uint16 *green;
+ uint16 *blue;
+ if ((TIFFGetField(image, TIFFTAG_COLORMAP, &red, &green, &blue)) == 0)
+ {
+ kdDebug(41008) << "Indexed image does not define a palette" << endl;
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_INVALID_ARG;
+ }
+
+ tiffReader = new KisTIFFReaderFromPalette( layer->paintDevice(), red, green, blue, poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor);
+ } else if(color_type == PHOTOMETRIC_YCBCR ) {
+ TIFFGetFieldDefaulted( image, TIFFTAG_YCBCRSUBSAMPLING, &hsubsampling, &vsubsampling );
+ lineSizeCoeffs[1] = hsubsampling;
+ lineSizeCoeffs[2] = hsubsampling;
+ uint16 position;
+ TIFFGetFieldDefaulted( image, TIFFTAG_YCBCRPOSITIONING, &position );
+ if( dstDepth == 8 )
+ {
+ tiffReader = new KisTIFFYCbCrReaderTarget8Bit(layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor, hsubsampling, vsubsampling, (KisTIFFYCbCr::Position)position);
+ } else if( dstDepth == 16 )
+ {
+ tiffReader = new KisTIFFYCbCrReaderTarget16Bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor, hsubsampling, vsubsampling, (KisTIFFYCbCr::Position)position);
+ }
+ } else if(dstDepth == 8)
+ {
+ tiffReader = new KisTIFFReaderTarget8bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor);
+ } else if(dstDepth == 16) {
+ tiffReader = new KisTIFFReaderTarget16bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor);
+ } else if(dstDepth == 32) {
+ tiffReader = new KisTIFFReaderTarget32bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor);
+ }
+
+ if(TIFFIsTiled(image))
+ {
+ kdDebug(41008) << "tiled image" << endl;
+ uint32 tileWidth, tileHeight;
+ uint32 x, y;
+ TIFFGetField(image, TIFFTAG_TILEWIDTH, &tileWidth);
+ TIFFGetField(image, TIFFTAG_TILELENGTH, &tileHeight);
+ uint32 linewidth = (tileWidth * depth * nbchannels) / 8;
+ if(planarconfig == PLANARCONFIG_CONTIG)
+ {
+ buf = _TIFFmalloc(TIFFTileSize(image));
+ if(depth < 16)
+ {
+ tiffstream = new TIFFStreamContigBelow16((uint8*)buf, depth, linewidth);
+ } else if(depth < 32)
+ {
+ tiffstream = new TIFFStreamContigBelow32((uint8*)buf, depth, linewidth);
+ } else {
+ tiffstream = new TIFFStreamContigAbove32((uint8*)buf, depth, linewidth);
+ }
+ } else {
+ ps_buf = new tdata_t[nbchannels];
+ uint32 * lineSizes = new uint32[nbchannels];
+ uint16 baseSize = TIFFTileSize(image)/nbchannels;
+ for(uint i = 0; i < nbchannels; i++)
+ {
+ ps_buf[i] = _TIFFmalloc(baseSize);
+ lineSizes[i] = baseSize / lineSizeCoeffs[i];
+ }
+ tiffstream = new TIFFStreamSeperate( (uint8**) ps_buf, nbchannels, depth, lineSizes);
+ delete [] lineSizes;
+ }
+ kdDebug(41008) << linewidth << " " << nbchannels << " " << layer->paintDevice()->colorSpace()->nColorChannels() << endl;
+ for (y = 0; y < height; y+= tileHeight)
+ {
+ for (x = 0; x < width; x += tileWidth)
+ {
+ kdDebug(41008) << "Reading tile x = " << x << " y = " << y << endl;
+ if( planarconfig == PLANARCONFIG_CONTIG )
+ {
+ TIFFReadTile(image, buf, x, y, 0, (tsample_t) -1);
+ } else {
+ for(uint i = 0; i < nbchannels; i++)
+ {
+ TIFFReadTile(image, ps_buf[i], x, y, 0, i);
+ }
+ }
+ uint32 realTileWidth = (x + tileWidth) < width ? tileWidth : width - x;
+ for (uint yintile = 0; y + yintile < height && yintile < tileHeight/vsubsampling; ) {
+ tiffReader->copyDataToChannels( x, y + yintile , realTileWidth, tiffstream);
+ yintile += 1;
+ tiffstream->moveToLine( yintile );
+ }
+ tiffstream->restart();
+ }
+ }
+ } else {
+ kdDebug(41008) << "striped image" << endl;
+ tsize_t stripsize = TIFFStripSize(image);
+ uint32 rowsPerStrip;
+ TIFFGetFieldDefaulted(image, TIFFTAG_ROWSPERSTRIP, &rowsPerStrip);
+ kdDebug() << rowsPerStrip << " " << height << endl;
+ rowsPerStrip = TQMIN(rowsPerStrip, height); // when TIFFNumberOfStrips(image) == 1 it might happen that rowsPerStrip is incorrectly set
+ if(planarconfig == PLANARCONFIG_CONTIG)
+ {
+ buf = _TIFFmalloc(stripsize);
+ if(depth < 16)
+ {
+ tiffstream = new TIFFStreamContigBelow16((uint8*)buf, depth, stripsize/rowsPerStrip);
+ } else if(depth < 32)
+ {
+ tiffstream = new TIFFStreamContigBelow32((uint8*)buf, depth, stripsize/rowsPerStrip);
+ } else {
+ tiffstream = new TIFFStreamContigAbove32((uint8*)buf, depth, stripsize/rowsPerStrip);
+ }
+ } else {
+ ps_buf = new tdata_t[nbchannels];
+ uint32 scanLineSize = stripsize/rowsPerStrip;
+ kdDebug(41008) << " scanLineSize for each plan = " << scanLineSize << endl;
+ uint32 * lineSizes = new uint32[nbchannels];
+ for(uint i = 0; i < nbchannels; i++)
+ {
+ ps_buf[i] = _TIFFmalloc(stripsize);
+ lineSizes[i] = scanLineSize / lineSizeCoeffs[i];
+ }
+ tiffstream = new TIFFStreamSeperate( (uint8**) ps_buf, nbchannels, depth, lineSizes);
+ delete [] lineSizes;
+ }
+
+ kdDebug(41008) << "Scanline size = " << TIFFRasterScanlineSize(image) << " / strip size = " << TIFFStripSize(image) << " / rowsPerStrip = " << rowsPerStrip << " stripsize/rowsPerStrip = " << stripsize/rowsPerStrip << endl;
+ uint32 y = 0;
+ kdDebug(41008) << " NbOfStrips = " << TIFFNumberOfStrips(image) << " rowsPerStrip = " << rowsPerStrip << " stripsize = " << stripsize << endl;
+ for (uint32 strip = 0; y < height; strip++)
+ {
+ if( planarconfig == PLANARCONFIG_CONTIG )
+ {
+ TIFFReadEncodedStrip(image, TIFFComputeStrip( image, y, 0 ) , buf, (tsize_t) -1);
+ } else {
+ for(uint i = 0; i < nbchannels; i++)
+ {
+ TIFFReadEncodedStrip(image, TIFFComputeStrip( image, y, i ), ps_buf[i], (tsize_t) -1);
+ }
+ }
+ for( uint32 yinstrip = 0 ; yinstrip < rowsPerStrip && y < height ; )
+ {
+ uint linesread = tiffReader->copyDataToChannels( 0, y, width, tiffstream);
+ y += linesread;
+ yinstrip += linesread;
+ tiffstream->moveToLine( yinstrip );
+ }
+ tiffstream->restart();
+ }
+ }
+ tiffReader->finalize();
+ delete lineSizeCoeffs;
+ delete tiffReader;
+ delete tiffstream;
+ if( planarconfig == PLANARCONFIG_CONTIG )
+ {
+ _TIFFfree(buf);
+ } else {
+ for(uint i = 0; i < nbchannels; i++)
+ {
+ _TIFFfree(ps_buf[i]);
+ }
+ delete[] ps_buf;
+ }
+
+ m_img->addLayer(layer, m_img->rootLayer(), 0);
+ return KisImageBuilder_RESULT_OK;
+}
+
+KisImageBuilder_Result KisTIFFConverter::buildImage(const KURL& uri)
+{
+ if (uri.isEmpty())
+ return KisImageBuilder_RESULT_NO_URI;
+
+ if (!TDEIO::NetAccess::exists(uri, false, tqApp -> mainWidget())) {
+ return KisImageBuilder_RESULT_NOT_EXIST;
+ }
+
+ // We're not set up to handle asynchronous loading at the moment.
+ KisImageBuilder_Result result = KisImageBuilder_RESULT_FAILURE;
+ TQString tmpFile;
+
+ if (TDEIO::NetAccess::download(uri, tmpFile, tqApp -> mainWidget())) {
+ KURL uriTF;
+ uriTF.setPath( tmpFile );
+ result = decode(uriTF);
+ TDEIO::NetAccess::removeTempFile(tmpFile);
+ }
+
+ return result;
+}
+
+
+KisImageSP KisTIFFConverter::image()
+{
+ return m_img;
+}
+
+
+KisImageBuilder_Result KisTIFFConverter::buildFile(const KURL& uri, KisImageSP img, KisTIFFOptions options)
+{
+ kdDebug(41008) << "Start writing TIFF File" << endl;
+ if (!img)
+ return KisImageBuilder_RESULT_EMPTY;
+
+ if (uri.isEmpty())
+ return KisImageBuilder_RESULT_NO_URI;
+
+ if (!uri.isLocalFile())
+ return KisImageBuilder_RESULT_NOT_LOCAL;
+
+ // Open file for writing
+ TIFF *image;
+ if((image = TIFFOpen(TQFile::encodeName(uri.path()), "w")) == NULL){
+ kdDebug(41008) << "Could not open the file for writting " << uri.path() << endl;
+ TIFFClose(image);
+ return (KisImageBuilder_RESULT_FAILURE);
+ }
+
+ // Set the document informations
+ KoDocumentInfo * info = m_doc->documentInfo();
+ KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(info->page( "about" ));
+ TQString title = aboutPage->title();
+ if(!title.isEmpty())
+ {
+ TIFFSetField(image, TIFFTAG_DOCUMENTNAME, title.ascii());
+ }
+ TQString abstract = aboutPage->abstract();
+ if(!abstract.isEmpty())
+ {
+ TIFFSetField(image, TIFFTAG_IMAGEDESCRIPTION, abstract.ascii());
+ }
+ KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor *>(info->page( "author" ));
+ TQString author = authorPage->fullName();
+ if(!author.isEmpty())
+ {
+ TIFFSetField(image, TIFFTAG_ARTIST, author.ascii());
+ }
+
+ KisTIFFWriterVisitor* visitor = new KisTIFFWriterVisitor(image, &options);
+ KisGroupLayer* root = dynamic_cast<KisGroupLayer*>(img->rootLayer().data());
+ if(root == 0)
+ {
+ TDEIO::del(uri);
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_FAILURE;
+ }
+ if(!visitor->visit( root ))
+ {
+ TDEIO::del(uri);
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_FAILURE;
+ }
+
+ TIFFClose(image);
+ return KisImageBuilder_RESULT_OK;
+}
+
+
+void KisTIFFConverter::cancel()
+{
+ m_stop = true;
+}
+
+#include "kis_tiff_converter.moc"