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