00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kis_tiff_converter.h"
00021
00022 #include <stdio.h>
00023
00024 #include <config.h>
00025 #include LCMS_HEADER
00026
00027 #include <qfile.h>
00028
00029 #include <kapplication.h>
00030 #include <KoDocumentInfo.h>
00031
00032 #include <kio/netaccess.h>
00033
00034 #include <kis_abstract_colorspace.h>
00035 #include <kis_colorspace_factory_registry.h>
00036 #include <kis_doc.h>
00037 #include <kis_image.h>
00038 #include <kis_iterators_pixel.h>
00039 #include <kis_layer.h>
00040 #include <kis_meta_registry.h>
00041 #include <kis_profile.h>
00042 #include <kis_group_layer.h>
00043 #include <kis_paint_layer.h>
00044
00045 #include "kis_tiff_reader.h"
00046 #include "kis_tiff_ycbcr_reader.h"
00047 #include "kis_tiff_stream.h"
00048 #include "kis_tiff_writer_visitor.h"
00049
00050 namespace {
00051
00052 QString getColorSpaceForColorType(uint16 color_type, uint16 color_nb_bits, TIFF *image, uint16 &nbchannels, uint16 &extrasamplescount, uint8 &destDepth, uint16 sampletype) {
00053 if(color_type == PHOTOMETRIC_MINISWHITE || color_type == PHOTOMETRIC_MINISBLACK)
00054 {
00055 if(nbchannels == 0) nbchannels = 1;
00056 extrasamplescount = nbchannels - 1;
00057 if(color_nb_bits <= 8)
00058 {
00059 destDepth = 8;
00060 return "GRAYA";
00061 } else {
00062 destDepth = 16;
00063 return "GRAYA16";
00064 }
00065 } else if(color_type == PHOTOMETRIC_RGB ) {
00066 if(nbchannels == 0) nbchannels = 3;
00067 extrasamplescount = nbchannels - 3;
00068 if(sampletype == SAMPLEFORMAT_IEEEFP)
00069 {
00070 if(color_nb_bits == 16)
00071 {
00072 destDepth = 16;
00073 return "RGBAF16HALF";
00074 } else if( color_nb_bits == 32) {
00075 destDepth = 32;
00076 return "RGBAF32";
00077 }
00078 return "";
00079 } else {
00080 if(color_nb_bits <= 8)
00081 {
00082 destDepth = 8;
00083 return "RGBA";
00084 } else {
00085 destDepth = 16;
00086 return "RGBA16";
00087 }
00088 }
00089 } else if(color_type == PHOTOMETRIC_YCBCR ) {
00090 if(nbchannels == 0) nbchannels = 3;
00091 extrasamplescount = nbchannels - 3;
00092 if(color_nb_bits <= 8)
00093 {
00094 destDepth = 8;
00095 return "YCbCrAU8";
00096 } else {
00097 destDepth = 16;
00098 return "YCbCrAU16";
00099 }
00100 } else if(color_type == PHOTOMETRIC_SEPARATED ) {
00101 if(nbchannels == 0) nbchannels = 4;
00102
00103 uint16 inkset;
00104 if((TIFFGetField(image, TIFFTAG_INKSET, &inkset) == 0)){
00105 kdDebug(41008) << "Image does not define the inkset." << endl;
00106 inkset = 2;
00107 }
00108 if(inkset != INKSET_CMYK)
00109 {
00110 kdDebug(41008) << "Unsupported inkset (right now, only CMYK is supported)" << endl;
00111 char** ink_names;
00112 uint16 numberofinks;
00113 if( TIFFGetField(image, TIFFTAG_INKNAMES, &ink_names) && TIFFGetField(image, TIFFTAG_NUMBEROFINKS, &numberofinks) )
00114 {
00115 kdDebug(41008) << "Inks are : " << endl;
00116 for(uint i = 0; i < numberofinks; i++)
00117 {
00118 kdDebug(41008) << ink_names[i] << endl;
00119 }
00120 } else {
00121 kdDebug(41008) << "inknames aren't defined !" << endl;
00122
00123 if( nbchannels - extrasamplescount != 4)
00124 {
00125 return "";
00126 }
00127 }
00128 }
00129 if(color_nb_bits <= 8)
00130 {
00131 destDepth = 8;
00132 return "CMYK";
00133 } else {
00134 destDepth = 16;
00135 return "CMYKA16";
00136 }
00137 } else if(color_type == PHOTOMETRIC_CIELAB
00138 #ifdef PHOTOMETRIC_ICCLAB
00139 || color_type == PHOTOMETRIC_ICCLAB
00140 #endif
00141 ) {
00142 destDepth = 16;
00143 if(nbchannels == 0) nbchannels = 3;
00144 extrasamplescount = nbchannels - 3;
00145 return "LABA";
00146 } else if(color_type == PHOTOMETRIC_PALETTE) {
00147 destDepth = 16;
00148 if(nbchannels == 0) nbchannels = 2;
00149 extrasamplescount = nbchannels - 2;
00150
00151 return "RGBA16";
00152 }
00153 return "";
00154 }
00155 }
00156
00157 KisTIFFConverter::KisTIFFConverter(KisDoc *doc, KisUndoAdapter *adapter)
00158 {
00159 m_doc = doc;
00160 m_adapter = adapter;
00161 m_job = 0;
00162 m_stop = false;
00163 }
00164
00165 KisTIFFConverter::~KisTIFFConverter()
00166 {
00167 }
00168
00169 KisImageBuilder_Result KisTIFFConverter::decode(const KURL& uri)
00170 {
00171 kdDebug(41008) << "Start decoding TIFF File" << endl;
00172
00173 TIFF *image = 0;
00174 if((image = TIFFOpen(QFile::encodeName(uri.path()), "r")) == NULL){
00175 kdDebug(41008) << "Could not open the file, either it doesn't exist, either it is not a TIFF : " << uri.path() << endl;
00176
00177 return (KisImageBuilder_RESULT_BAD_FETCH);
00178 }
00179 do {
00180 kdDebug(41008) << "Read new sub-image" << endl;
00181 KisImageBuilder_Result result = readTIFFDirectory(image);
00182 if(result != KisImageBuilder_RESULT_OK){
00183 return result;
00184 }
00185 } while (TIFFReadDirectory(image));
00186
00187 TIFFClose(image);
00188 return KisImageBuilder_RESULT_OK;
00189 }
00190
00191 KisImageBuilder_Result KisTIFFConverter::readTIFFDirectory( TIFF* image)
00192 {
00193
00194 uint32 width, height;
00195 if(TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width) == 0){
00196 kdDebug(41008) << "Image does not define its width" << endl;
00197 TIFFClose(image);
00198 return KisImageBuilder_RESULT_INVALID_ARG;
00199 }
00200 if(TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height) == 0){
00201 kdDebug(41008) << "Image does not define its height" << endl;
00202 TIFFClose(image);
00203 return KisImageBuilder_RESULT_INVALID_ARG;
00204 }
00205 uint16 depth;
00206 if((TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &depth) == 0)){
00207 kdDebug(41008) << "Image does not define its depth" << endl;
00208 depth = 1;
00209 }
00210 uint16 sampletype;
00211 if((TIFFGetField(image, TIFFTAG_SAMPLEFORMAT, &sampletype) == 0)){
00212 kdDebug(41008) << "Image does not define its sample type" << endl;
00213 sampletype = SAMPLEFORMAT_UINT;
00214 }
00215
00216 uint16 nbchannels;
00217 if(TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &nbchannels) == 0){
00218 kdDebug(41008) << "Image has an undefined number of samples per pixel" << endl;
00219 nbchannels = 0;
00220 }
00221
00222 uint16 *sampleinfo, extrasamplescount;
00223 if(TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extrasamplescount, &sampleinfo) == 0)
00224 {
00225 extrasamplescount = 0;
00226 }
00227
00228 uint16 color_type;
00229 if(TIFFGetField(image, TIFFTAG_PHOTOMETRIC, &color_type) == 0){
00230 kdDebug(41008) << "Image has an undefined photometric interpretation" << endl;
00231 color_type = PHOTOMETRIC_MINISWHITE;
00232 }
00233 uint8 dstDepth;
00234 QString csName = getColorSpaceForColorType(color_type, depth, image, nbchannels, extrasamplescount, dstDepth,sampletype);
00235 if(csName.isEmpty()) {
00236 kdDebug(41008) << "Image has an unsupported colorspace : " << color_type << " for this depth : "<< depth << endl;
00237 TIFFClose(image);
00238 return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE;
00239 }
00240 kdDebug(41008) << "Colorspace is : " << csName << " with a depth of " << depth << " and with a nb of channels of " << nbchannels << endl;
00241
00242
00243 kdDebug() << "Reading profile" << endl;
00244 KisProfile* profile = 0;
00245 DWORD EmbedLen;
00246 LPBYTE EmbedBuffer;
00247
00248 if (TIFFGetField(image, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer)) {
00249 kdDebug(41008) << "Profile found" << endl;
00250 QByteArray rawdata;
00251 rawdata.resize(EmbedLen);
00252 memcpy(rawdata.data(), EmbedBuffer, EmbedLen);
00253 profile = new KisProfile(rawdata);
00254 } else {
00255 kdDebug(41008) << "No Profile found" << endl;
00256 }
00257
00258
00259 KisColorSpace* cs = 0;
00260 if (profile && profile->isSuitableForOutput())
00261 {
00262 kdDebug(41008) << "image has embedded profile: " << profile -> productName() << "\n";
00263 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(csName, profile);
00264 }
00265 else
00266 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName,""),"");
00267
00268 if(cs == 0) {
00269 kdDebug(41008) << "Colorspace " << csName << " is not available, please check your installation." << endl;
00270 TIFFClose(image);
00271 return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE;
00272 }
00273
00274
00275 cmsHTRANSFORM transform = 0;
00276 if(profile && !profile->isSuitableForOutput())
00277 {
00278 kdDebug(41008) << "The profile can't be used in krita, need conversion" << endl;
00279 transform = cmsCreateTransform(profile->profile(), cs->colorSpaceType(),
00280 cs->getProfile()->profile() , cs->colorSpaceType(),
00281 INTENT_PERCEPTUAL, 0);
00282 }
00283
00284
00285
00286 int8 alphapos = -1;
00287
00288 kdDebug(41008) << "There are " << nbchannels << " channels and " << extrasamplescount << " extra channels" << endl;
00289 if(sampleinfo)
00290 {
00291 for(int i = 0; i < extrasamplescount; i ++)
00292 {
00293 kdDebug(41008) << i << " " << extrasamplescount << " " << (cs->nColorChannels()) << nbchannels << " " << sampleinfo[i] << endl;
00294 if(sampleinfo[i] == EXTRASAMPLE_ASSOCALPHA)
00295 {
00296
00297
00298 alphapos = i;
00299 }
00300
00301 if (sampleinfo[i] == EXTRASAMPLE_UNASSALPHA)
00302 {
00303
00304 alphapos = i;
00305 }
00306 }
00307 }
00308
00309
00310 KoDocumentInfo * info = m_doc->documentInfo();
00311 KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(info->page( "about" ));
00312 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor *>(info->page( "author"));
00313 char* text;
00314 if (TIFFGetField(image, TIFFTAG_ARTIST, &text)) {
00315 authorPage->setFullName(text);
00316 }
00317 if (TIFFGetField(image, TIFFTAG_DOCUMENTNAME, &text)) {
00318 aboutPage->setTitle(text);
00319 }
00320 if (TIFFGetField(image,TIFFTAG_IMAGEDESCRIPTION,&text) ) {
00321 aboutPage->setAbstract( text );
00322 }
00323
00324
00325
00326 uint16 planarconfig;
00327 if(TIFFGetField(image, TIFFTAG_PLANARCONFIG, &planarconfig) == 0)
00328 {
00329 kdDebug(41008) << "Plannar configuration is not define" << endl;
00330 TIFFClose(image);
00331 return KisImageBuilder_RESULT_INVALID_ARG;
00332 }
00333
00334 if( ! m_img ) {
00335 m_img = new KisImage(m_doc->undoAdapter(), width, height, cs, "built image");
00336 Q_CHECK_PTR(m_img);
00337 m_img->blockSignals(true);
00338 if(profile)
00339 {
00340 m_img -> addAnnotation( profile->annotation() );
00341 }
00342 } else {
00343 if( m_img->width() < (Q_INT32)width || m_img->height() < (Q_INT32)height)
00344 {
00345 Q_UINT32 newwidth = (m_img->width() < (Q_INT32)width) ? width : m_img->width();
00346 Q_UINT32 newheight = (m_img->height() < (Q_INT32)height) ? height : m_img->height();
00347 m_img->resize(newwidth, newheight, false);
00348 }
00349 }
00350 KisPaintLayer* layer = new KisPaintLayer(m_img, m_img -> nextLayerName(), Q_UINT8_MAX);
00351 tdata_t buf = 0;
00352 tdata_t* ps_buf = 0;
00353 TIFFStreamBase* tiffstream;
00354
00355 KisTIFFReaderBase* tiffReader = 0;
00356
00357 Q_UINT8 poses[5];
00358 KisTIFFPostProcessor* postprocessor = 0;
00359
00360
00361 uint8 nbcolorsamples = nbchannels - extrasamplescount;
00362 switch(color_type)
00363 {
00364 case PHOTOMETRIC_MINISWHITE:
00365 {
00366 poses[0] = 0; poses[1] = 1;
00367 postprocessor = new KisTIFFPostProcessorInvert(nbcolorsamples);
00368 }
00369 break;
00370 case PHOTOMETRIC_MINISBLACK:
00371 {
00372 poses[0] = 0; poses[1] = 1;
00373 postprocessor = new KisTIFFPostProcessor(nbcolorsamples);
00374 }
00375 break;
00376 case PHOTOMETRIC_CIELAB:
00377 {
00378 poses[0] = 0; poses[1] = 1; poses[2] = 2; poses[3] = 3;
00379 postprocessor = new KisTIFFPostProcessor(nbcolorsamples);
00380 }
00381 break;
00382 #ifdef PHOTOMETRIC_ICCLAB
00383 case PHOTOMETRIC_ICCLAB:
00384 {
00385 poses[0] = 0; poses[1] = 1; poses[2] = 2; poses[3] = 3;
00386 postprocessor = new KisTIFFPostProcessorICCLABtoCIELAB(nbcolorsamples);
00387 }
00388 break;
00389 #endif
00390 case PHOTOMETRIC_RGB:
00391 {
00392 poses[0] = 2; poses[1] = 1; poses[2] = 0; poses[3] = 3;
00393 postprocessor = new KisTIFFPostProcessor(nbcolorsamples);
00394 }
00395 break;
00396 case PHOTOMETRIC_SEPARATED:
00397 {
00398 poses[0] = 0; poses[1] = 1; poses[2] = 2; poses[3] = 3; poses[4] = 4;
00399 postprocessor = new KisTIFFPostProcessor(nbcolorsamples);
00400 }
00401 break;
00402 default:
00403 break;
00404 }
00405
00406
00407
00408 uint16 * lineSizeCoeffs = new uint16[nbchannels];
00409 uint16 vsubsampling = 1;
00410 uint16 hsubsampling = 1;
00411 for(uint i = 0; i < nbchannels; i++)
00412 {
00413 lineSizeCoeffs[i] = 1;
00414 }
00415 if( color_type == PHOTOMETRIC_PALETTE)
00416 {
00417 uint16 *red;
00418 uint16 *green;
00419 uint16 *blue;
00420 if ((TIFFGetField(image, TIFFTAG_COLORMAP, &red, &green, &blue)) == 0)
00421 {
00422 kdDebug(41008) << "Indexed image does not define a palette" << endl;
00423 TIFFClose(image);
00424 return KisImageBuilder_RESULT_INVALID_ARG;
00425 }
00426
00427 tiffReader = new KisTIFFReaderFromPalette( layer->paintDevice(), red, green, blue, poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor);
00428 } else if(color_type == PHOTOMETRIC_YCBCR ) {
00429 TIFFGetFieldDefaulted( image, TIFFTAG_YCBCRSUBSAMPLING, &hsubsampling, &vsubsampling );
00430 lineSizeCoeffs[1] = hsubsampling;
00431 lineSizeCoeffs[2] = hsubsampling;
00432 uint16 position;
00433 TIFFGetFieldDefaulted( image, TIFFTAG_YCBCRPOSITIONING, &position );
00434 if( dstDepth == 8 )
00435 {
00436 tiffReader = new KisTIFFYCbCrReaderTarget8Bit(layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor, hsubsampling, vsubsampling, (KisTIFFYCbCr::Position)position);
00437 } else if( dstDepth == 16 )
00438 {
00439 tiffReader = new KisTIFFYCbCrReaderTarget16Bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor, hsubsampling, vsubsampling, (KisTIFFYCbCr::Position)position);
00440 }
00441 } else if(dstDepth == 8)
00442 {
00443 tiffReader = new KisTIFFReaderTarget8bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor);
00444 } else if(dstDepth == 16) {
00445 tiffReader = new KisTIFFReaderTarget16bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor);
00446 } else if(dstDepth == 32) {
00447 tiffReader = new KisTIFFReaderTarget32bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor);
00448 }
00449
00450 if(TIFFIsTiled(image))
00451 {
00452 kdDebug(41008) << "tiled image" << endl;
00453 uint32 tileWidth, tileHeight;
00454 uint32 x, y;
00455 TIFFGetField(image, TIFFTAG_TILEWIDTH, &tileWidth);
00456 TIFFGetField(image, TIFFTAG_TILELENGTH, &tileHeight);
00457 uint32 linewidth = (tileWidth * depth * nbchannels) / 8;
00458 if(planarconfig == PLANARCONFIG_CONTIG)
00459 {
00460 buf = _TIFFmalloc(TIFFTileSize(image));
00461 if(depth < 16)
00462 {
00463 tiffstream = new TIFFStreamContigBelow16((uint8*)buf, depth, linewidth);
00464 } else if(depth < 32)
00465 {
00466 tiffstream = new TIFFStreamContigBelow32((uint8*)buf, depth, linewidth);
00467 } else {
00468 tiffstream = new TIFFStreamContigAbove32((uint8*)buf, depth, linewidth);
00469 }
00470 } else {
00471 ps_buf = new tdata_t[nbchannels];
00472 uint32 * lineSizes = new uint32[nbchannels];
00473 uint16 baseSize = TIFFTileSize(image)/nbchannels;
00474 for(uint i = 0; i < nbchannels; i++)
00475 {
00476 ps_buf[i] = _TIFFmalloc(baseSize);
00477 lineSizes[i] = baseSize / lineSizeCoeffs[i];
00478 }
00479 tiffstream = new TIFFStreamSeperate( (uint8**) ps_buf, nbchannels, depth, lineSizes);
00480 delete [] lineSizes;
00481 }
00482 kdDebug(41008) << linewidth << " " << nbchannels << " " << layer->paintDevice()->colorSpace()->nColorChannels() << endl;
00483 for (y = 0; y < height; y+= tileHeight)
00484 {
00485 for (x = 0; x < width; x += tileWidth)
00486 {
00487 kdDebug(41008) << "Reading tile x = " << x << " y = " << y << endl;
00488 if( planarconfig == PLANARCONFIG_CONTIG )
00489 {
00490 TIFFReadTile(image, buf, x, y, 0, (tsample_t) -1);
00491 } else {
00492 for(uint i = 0; i < nbchannels; i++)
00493 {
00494 TIFFReadTile(image, ps_buf[i], x, y, 0, i);
00495 }
00496 }
00497 uint32 realTileWidth = (x + tileWidth) < width ? tileWidth : width - x;
00498 for (uint yintile = 0; y + yintile < height && yintile < tileHeight/vsubsampling; ) {
00499 uint linesreaded = tiffReader->copyDataToChannels( x, y + yintile , realTileWidth, tiffstream);
00500 yintile += 1;
00501 tiffstream->moveToLine( yintile );
00502 }
00503 tiffstream->restart();
00504 }
00505 }
00506 } else {
00507 kdDebug(41008) << "striped image" << endl;
00508 tsize_t stripsize = TIFFStripSize(image);
00509 uint32 rowsPerStrip;
00510 TIFFGetFieldDefaulted(image, TIFFTAG_ROWSPERSTRIP, &rowsPerStrip);
00511 kdDebug() << rowsPerStrip << " " << height << endl;
00512 rowsPerStrip = QMIN(rowsPerStrip, height);
00513 if(planarconfig == PLANARCONFIG_CONTIG)
00514 {
00515 buf = _TIFFmalloc(stripsize);
00516 if(depth < 16)
00517 {
00518 tiffstream = new TIFFStreamContigBelow16((uint8*)buf, depth, stripsize/rowsPerStrip);
00519 } else if(depth < 32)
00520 {
00521 tiffstream = new TIFFStreamContigBelow32((uint8*)buf, depth, stripsize/rowsPerStrip);
00522 } else {
00523 tiffstream = new TIFFStreamContigAbove32((uint8*)buf, depth, stripsize/rowsPerStrip);
00524 }
00525 } else {
00526 ps_buf = new tdata_t[nbchannels];
00527 uint32 scanLineSize = stripsize/rowsPerStrip;
00528 kdDebug(41008) << " scanLineSize for each plan = " << scanLineSize << endl;
00529 uint32 * lineSizes = new uint32[nbchannels];
00530 for(uint i = 0; i < nbchannels; i++)
00531 {
00532 ps_buf[i] = _TIFFmalloc(stripsize);
00533 lineSizes[i] = scanLineSize / lineSizeCoeffs[i];
00534 }
00535 tiffstream = new TIFFStreamSeperate( (uint8**) ps_buf, nbchannels, depth, lineSizes);
00536 delete [] lineSizes;
00537 }
00538
00539 kdDebug(41008) << "Scanline size = " << TIFFRasterScanlineSize(image) << " / strip size = " << TIFFStripSize(image) << " / rowsPerStrip = " << rowsPerStrip << " stripsize/rowsPerStrip = " << stripsize/rowsPerStrip << endl;
00540 uint32 y = 0;
00541 kdDebug(41008) << " NbOfStrips = " << TIFFNumberOfStrips(image) << " rowsPerStrip = " << rowsPerStrip << " stripsize = " << stripsize << endl;
00542 for (uint32 strip = 0; y < height; strip++)
00543 {
00544 if( planarconfig == PLANARCONFIG_CONTIG )
00545 {
00546 TIFFReadEncodedStrip(image, TIFFComputeStrip( image, y, 0 ) , buf, (tsize_t) -1);
00547 } else {
00548 for(uint i = 0; i < nbchannels; i++)
00549 {
00550 TIFFReadEncodedStrip(image, TIFFComputeStrip( image, y, i ), ps_buf[i], (tsize_t) -1);
00551 }
00552 }
00553 for( uint32 yinstrip = 0 ; yinstrip < rowsPerStrip && y < height ; )
00554 {
00555 uint linesreaded = tiffReader->copyDataToChannels( 0, y, width, tiffstream);
00556 y += linesreaded;
00557 yinstrip += linesreaded;
00558 tiffstream->moveToLine( yinstrip );
00559 }
00560 tiffstream->restart();
00561 }
00562 }
00563 tiffReader->finalize();
00564 delete lineSizeCoeffs;
00565 delete tiffReader;
00566 delete tiffstream;
00567 if( planarconfig == PLANARCONFIG_CONTIG )
00568 {
00569 _TIFFfree(buf);
00570 } else {
00571 for(uint i = 0; i < nbchannels; i++)
00572 {
00573 _TIFFfree(ps_buf[i]);
00574 }
00575 delete[] ps_buf;
00576 }
00577
00578 m_img->addLayer(layer, m_img->rootLayer(), 0);
00579 return KisImageBuilder_RESULT_OK;
00580 }
00581
00582 KisImageBuilder_Result KisTIFFConverter::buildImage(const KURL& uri)
00583 {
00584 if (uri.isEmpty())
00585 return KisImageBuilder_RESULT_NO_URI;
00586
00587 if (!KIO::NetAccess::exists(uri, false, qApp -> mainWidget())) {
00588 return KisImageBuilder_RESULT_NOT_EXIST;
00589 }
00590
00591
00592 KisImageBuilder_Result result = KisImageBuilder_RESULT_FAILURE;
00593 QString tmpFile;
00594
00595 if (KIO::NetAccess::download(uri, tmpFile, qApp -> mainWidget())) {
00596 KURL uriTF;
00597 uriTF.setPath( tmpFile );
00598 result = decode(uriTF);
00599 KIO::NetAccess::removeTempFile(tmpFile);
00600 }
00601
00602 return result;
00603 }
00604
00605
00606 KisImageSP KisTIFFConverter::image()
00607 {
00608 return m_img;
00609 }
00610
00611
00612 KisImageBuilder_Result KisTIFFConverter::buildFile(const KURL& uri, KisImageSP img, KisTIFFOptions options)
00613 {
00614 kdDebug(41008) << "Start writing TIFF File" << endl;
00615 if (!img)
00616 return KisImageBuilder_RESULT_EMPTY;
00617
00618 if (uri.isEmpty())
00619 return KisImageBuilder_RESULT_NO_URI;
00620
00621 if (!uri.isLocalFile())
00622 return KisImageBuilder_RESULT_NOT_LOCAL;
00623
00624
00625 TIFF *image;
00626 if((image = TIFFOpen(QFile::encodeName(uri.path()), "w")) == NULL){
00627 kdDebug(41008) << "Could not open the file for writting " << uri.path() << endl;
00628 TIFFClose(image);
00629 return (KisImageBuilder_RESULT_FAILURE);
00630 }
00631
00632
00633 KoDocumentInfo * info = m_doc->documentInfo();
00634 KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(info->page( "about" ));
00635 QString title = aboutPage->title();
00636 if(!title.isEmpty())
00637 {
00638 TIFFSetField(image, TIFFTAG_DOCUMENTNAME, title.ascii());
00639 }
00640 QString abstract = aboutPage->abstract();
00641 if(!abstract.isEmpty())
00642 {
00643 TIFFSetField(image, TIFFTAG_IMAGEDESCRIPTION, abstract.ascii());
00644 }
00645 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor *>(info->page( "author" ));
00646 QString author = authorPage->fullName();
00647 if(!author.isEmpty())
00648 {
00649 TIFFSetField(image, TIFFTAG_ARTIST, author.ascii());
00650 }
00651
00652 KisTIFFWriterVisitor* visitor = new KisTIFFWriterVisitor(image, &options);
00653 KisGroupLayer* root = dynamic_cast<KisGroupLayer*>(img->rootLayer().data());
00654 if(root == 0)
00655 {
00656 KIO::del(uri);
00657 TIFFClose(image);
00658 return KisImageBuilder_RESULT_FAILURE;
00659 }
00660 if(!visitor->visit( root ))
00661 {
00662 KIO::del(uri);
00663 TIFFClose(image);
00664 return KisImageBuilder_RESULT_FAILURE;
00665 }
00666
00667 TIFFClose(image);
00668 return KisImageBuilder_RESULT_OK;
00669 }
00670
00671
00672 void KisTIFFConverter::cancel()
00673 {
00674 m_stop = true;
00675 }
00676
00677 #include "kis_tiff_converter.moc"