You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/filters/chalk/tiff/kis_tiff_converter.cc

678 lines
25 KiB

/*
* 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 <kapplication.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"