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