00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kis_png_converter.h"
00022
00023 #include <stdio.h>
00024
00025 #include <qfile.h>
00026
00027 #include <kapplication.h>
00028 #include <KoDocumentInfo.h>
00029
00030 #include <kio/netaccess.h>
00031
00032 #include <kis_abstract_colorspace.h>
00033 #include <kis_colorspace_factory_registry.h>
00034 #include <kis_doc.h>
00035 #include <kis_image.h>
00036 #include <kis_iterators_pixel.h>
00037 #include <kis_layer.h>
00038 #include <kis_meta_registry.h>
00039 #include <kis_profile.h>
00040 #include <kis_paint_layer.h>
00041 #include <kis_group_layer.h>
00042
00043 namespace {
00044
00045 const Q_UINT8 PIXEL_BLUE = 0;
00046 const Q_UINT8 PIXEL_GREEN = 1;
00047 const Q_UINT8 PIXEL_RED = 2;
00048 const Q_UINT8 PIXEL_ALPHA = 3;
00049
00050
00051 int getColorTypeforColorSpace( KisColorSpace * cs , bool alpha)
00052 {
00053 if ( cs->id() == KisID("GRAYA") || cs->id() == KisID("GRAYA16") )
00054 {
00055 return alpha ? PNG_COLOR_TYPE_GRAY_ALPHA : PNG_COLOR_TYPE_GRAY;
00056 }
00057 if ( cs->id() == KisID("RGBA") || cs->id() == KisID("RGBA16") )
00058 {
00059 return alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB;
00060 }
00061
00062 kdDebug(41008) << "Cannot export images in " + cs->id().name() + " yet.\n";
00063 return -1;
00064
00065 }
00066
00067
00068 QString getColorSpaceForColorType(int color_type,int color_nb_bits) {
00069 if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
00070 {
00071 switch(color_nb_bits)
00072 {
00073 case 8:
00074 return "GRAYA";
00075 case 16:
00076 return "GRAYA16";
00077 }
00078 } else if(color_type == PNG_COLOR_TYPE_RGB_ALPHA || color_type == PNG_COLOR_TYPE_RGB) {
00079 switch(color_nb_bits)
00080 {
00081 case 8:
00082 return "RGBA";
00083 case 16:
00084 return "RGBA16";
00085 }
00086 } else if(color_type == PNG_COLOR_TYPE_PALETTE) {
00087 return "RGBA";
00088 }
00089 return "";
00090 }
00091
00092
00093 void fillText(png_text* p_text, char* key, QString& text)
00094 {
00095 p_text->compression = PNG_TEXT_COMPRESSION_zTXt;
00096 p_text->key = key;
00097 char* textc = new char[text.length()+1];
00098 strcpy(textc, text.ascii());
00099 p_text->text = textc;
00100 p_text->text_length = text.length()+1;
00101 }
00102
00103 }
00104
00105 KisPNGConverter::KisPNGConverter(KisDoc *doc, KisUndoAdapter *adapter)
00106 {
00107 Q_ASSERT(doc);
00108 Q_ASSERT(adapter);
00109
00110 m_doc = doc;
00111 m_adapter = adapter;
00112 m_stop = false;
00113 m_max_row = 0;
00114 m_img = 0;
00115 }
00116
00117 KisPNGConverter::~KisPNGConverter()
00118 {
00119 }
00120
00121 KisImageBuilder_Result KisPNGConverter::decode(const KURL& uri)
00122 {
00123 kdDebug(41008) << "Start decoding PNG File" << endl;
00124
00125 kdDebug(41008) << QFile::encodeName(uri.path()) << " " << uri.path() << " " << uri << endl;
00126 FILE *fp = fopen(QFile::encodeName(uri.path()), "rb");
00127 if (!fp)
00128 {
00129 return (KisImageBuilder_RESULT_NOT_EXIST);
00130 }
00131 png_byte signature[8];
00132 fread(signature, 1, 8, fp);
00133 if (!png_check_sig(signature, 8))
00134 {
00135 return (KisImageBuilder_RESULT_BAD_FETCH);
00136 }
00137
00138
00139 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL);
00140 if (!KisImageBuilder_RESULT_FAILURE)
00141 return (KisImageBuilder_RESULT_FAILURE);
00142
00143 png_infop info_ptr = png_create_info_struct(png_ptr);
00144 if (!info_ptr)
00145 {
00146 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
00147 return (KisImageBuilder_RESULT_FAILURE);
00148 }
00149
00150 png_infop end_info = png_create_info_struct(png_ptr);
00151 if (!end_info)
00152 {
00153 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
00154 return (KisImageBuilder_RESULT_FAILURE);
00155 }
00156
00157
00158 if (setjmp(png_jmpbuf(png_ptr)))
00159 {
00160 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00161 fclose(fp);
00162 return (KisImageBuilder_RESULT_FAILURE);
00163 }
00164
00165 png_init_io(png_ptr, fp);
00166 png_set_sig_bytes(png_ptr, 8);
00167
00168
00169 png_read_info(png_ptr, info_ptr);
00170
00171
00172 png_uint_32 width, height;
00173 int color_nb_bits, color_type;
00174 png_get_IHDR(png_ptr, info_ptr, &width, &height, &color_nb_bits, &color_type, NULL, NULL, NULL);
00175
00176
00177 #ifndef WORDS_BIGENDIAN
00178 if (color_nb_bits > 8 )
00179 png_set_swap(png_ptr);
00180 #endif
00181
00182
00183 QString csName = getColorSpaceForColorType(color_type, color_nb_bits);
00184 if(csName.isEmpty()) {
00185 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00186 return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE;
00187 }
00188 bool hasalpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA || color_type == PNG_COLOR_TYPE_GRAY_ALPHA);
00189
00190
00191 png_charp profile_name, profile_data;
00192 int compression_type;
00193 png_uint_32 proflen;
00194
00195 KisProfile* profile = 0;
00196 if(png_get_iCCP(png_ptr, info_ptr, &profile_name, &compression_type, &profile_data, &proflen))
00197 {
00198 QByteArray profile_rawdata;
00199
00200 if (QString::compare(profile_name, "icc") == 0) {
00201 profile_rawdata.resize(proflen);
00202 memcpy(profile_rawdata.data(), profile_data, proflen);
00203 profile = new KisProfile(profile_rawdata);
00204 Q_CHECK_PTR(profile);
00205 if (profile) {
00206 kdDebug(41008) << "profile name: " << profile->productName() << " profile description: " << profile->productDescription() << " information sur le produit: " << profile->productInfo() << endl;
00207 if(!profile->isSuitableForOutput())
00208 {
00209 kdDebug(41008) << "the profile is not suitable for output and therefore cannot be used in krita, we need to convert the image to a standard profile" << endl;
00210 }
00211 }
00212 }
00213 }
00214
00215
00216 KisColorSpace* cs;
00217 if (profile && profile->isSuitableForOutput())
00218 {
00219 kdDebug(41008) << "image has embedded profile: " << profile -> productName() << "\n";
00220 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(csName, profile);
00221 }
00222 else
00223 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName,""),"");
00224
00225 if(cs == 0)
00226 {
00227 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00228 return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE;
00229 }
00230
00231
00232 cmsHTRANSFORM transform = 0;
00233 if(profile && !profile->isSuitableForOutput())
00234 {
00235 transform = cmsCreateTransform(profile->profile(), cs->colorSpaceType(),
00236 cs->getProfile()->profile() , cs->colorSpaceType(),
00237 INTENT_PERCEPTUAL, 0);
00238 }
00239
00240
00241 png_text* text_ptr;
00242 int num_comments;
00243 png_get_text(png_ptr, info_ptr, &text_ptr, &num_comments);
00244 KoDocumentInfo * info = m_doc->documentInfo();
00245 KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(info->page( "about" ));
00246 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor *>(info->page( "author"));
00247 kdDebug(41008) << "There are " << num_comments << " comments in the text" << endl;
00248 for(int i = 0; i < num_comments; i++)
00249 {
00250 kdDebug(41008) << "key is " << text_ptr[i].key << " containing " << text_ptr[i].text << endl;
00251 if(QString::compare(text_ptr[i].key, "title") == 0)
00252 {
00253 aboutPage->setTitle(text_ptr[i].text);
00254 } else if(QString::compare(text_ptr[i].key, "abstract") == 0)
00255 {
00256 aboutPage->setAbstract(text_ptr[i].text);
00257 } else if(QString::compare(text_ptr[i].key, "author") == 0)
00258 {
00259 authorPage->setFullName(text_ptr[i].text);
00260 }
00261 }
00262
00263
00264 png_bytepp row_pointers = new png_bytep[height];
00265 png_uint_32 row_index = 0;
00266 try
00267 {
00268 png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
00269 for(; row_index < height; row_index++)
00270 {
00271 row_pointers[row_index] = new png_byte[rowbytes];
00272 }
00273 }
00274 catch(std::bad_alloc& e)
00275 {
00276
00277
00278 kdDebug(41008) << "bad alloc: " << e.what() << endl;
00279
00280 for (png_uint_32 y = 0; y < row_index; y++) {
00281 delete[] row_pointers[y];
00282 }
00283 delete [] row_pointers;
00284 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00285 return (KisImageBuilder_RESULT_FAILURE);
00286 }
00287
00288
00289 png_colorp palette ;
00290 int num_palette;
00291 if(color_type == PNG_COLOR_TYPE_PALETTE) {
00292 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
00293 }
00294
00295
00296 png_read_image(png_ptr, row_pointers);
00297
00298
00299 png_read_end(png_ptr, end_info);
00300 fclose(fp);
00301
00302
00303 if( ! m_img) {
00304 m_img = new KisImage(m_doc->undoAdapter(), width, height, cs, "built image");
00305 m_img->blockSignals(true);
00306 Q_CHECK_PTR(m_img);
00307 if(profile && !profile->isSuitableForOutput())
00308 {
00309 m_img -> addAnnotation( profile->annotation() );
00310 }
00311 }
00312
00313 KisPaintLayer* layer = new KisPaintLayer(m_img, m_img -> nextLayerName(), Q_UINT8_MAX);
00314 for (png_uint_32 y = 0; y < height; y++) {
00315 KisHLineIterator it = layer -> paintDevice() -> createHLineIterator(0, y, width, true);
00316 switch(color_type)
00317 {
00318 case PNG_COLOR_TYPE_GRAY:
00319 case PNG_COLOR_TYPE_GRAY_ALPHA:
00320 if(color_nb_bits == 16)
00321 {
00322 Q_UINT16 *src = reinterpret_cast<Q_UINT16 *>(row_pointers[y]);
00323 while (!it.isDone()) {
00324 Q_UINT16 *d = reinterpret_cast<Q_UINT16 *>(it.rawData());
00325 d[0] = *(src++);
00326 if(transform) cmsDoTransform(transform, d, d, 1);
00327 if(hasalpha) d[1] = *(src++);
00328 else d[1] = Q_UINT16_MAX;
00329 ++it;
00330 }
00331 } else {
00332 Q_UINT8 *src = row_pointers[y];
00333 while (!it.isDone()) {
00334 Q_UINT8 *d = it.rawData();
00335 d[0] = *(src++);
00336 if(transform) cmsDoTransform(transform, d, d, 1);
00337 if(hasalpha) d[1] = *(src++);
00338 else d[1] = Q_UINT8_MAX;
00339 ++it;
00340 }
00341 }
00342
00343 break;
00344 case PNG_COLOR_TYPE_RGB:
00345 case PNG_COLOR_TYPE_RGB_ALPHA:
00346 if(color_nb_bits == 16)
00347 {
00348 Q_UINT16 *src = reinterpret_cast<Q_UINT16 *>(row_pointers[y]);
00349 while (!it.isDone()) {
00350 Q_UINT16 *d = reinterpret_cast<Q_UINT16 *>(it.rawData());
00351 d[2] = *(src++);
00352 d[1] = *(src++);
00353 d[0] = *(src++);
00354 if(transform) cmsDoTransform(transform, d, d, 1);
00355 if(hasalpha) d[3] = *(src++);
00356 else d[3] = Q_UINT16_MAX;
00357 ++it;
00358 }
00359 } else {
00360 Q_UINT8 *src = row_pointers[y];
00361 while (!it.isDone()) {
00362 Q_UINT8 *d = it.rawData();
00363 d[2] = *(src++);
00364 d[1] = *(src++);
00365 d[0] = *(src++);
00366 if(transform) cmsDoTransform(transform, d, d, 1);
00367 if(hasalpha) d[3] = *(src++);
00368 else d[3] = Q_UINT8_MAX;
00369 ++it;
00370 }
00371 }
00372 break;
00373 case PNG_COLOR_TYPE_PALETTE:
00374 switch(color_nb_bits)
00375 {
00376 case 8:
00377 {
00378 Q_UINT8 *src = row_pointers[y];
00379 while (!it.isDone()) {
00380 Q_UINT8 *d = it.rawData();
00381 png_color c = palette[*(src++)];
00382 d[2] = c.red;
00383 d[1] = c.green;
00384 d[0] = c.blue;
00385 d[3] = Q_UINT8_MAX;
00386 ++it;
00387 }
00388 break;
00389 }
00390 default:
00391 return KisImageBuilder_RESULT_UNSUPPORTED;
00392 }
00393
00394 break;
00395 default:
00396 return KisImageBuilder_RESULT_UNSUPPORTED;
00397 }
00398 }
00399 m_img->addLayer(layer, m_img->rootLayer(), 0);
00400
00401
00402 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00403
00404 for (png_uint_32 y = 0; y < height; y++) {
00405 delete[] row_pointers[y];
00406 }
00407 delete [] row_pointers;
00408
00409 return KisImageBuilder_RESULT_OK;
00410
00411 }
00412
00413 KisImageBuilder_Result KisPNGConverter::buildImage(const KURL& uri)
00414 {
00415 kdDebug(41008) << QFile::encodeName(uri.path()) << " " << uri.path() << " " << uri << endl;
00416 if (uri.isEmpty())
00417 return KisImageBuilder_RESULT_NO_URI;
00418
00419 if (!KIO::NetAccess::exists(uri, false, qApp -> mainWidget())) {
00420 return KisImageBuilder_RESULT_NOT_EXIST;
00421 }
00422
00423
00424 KisImageBuilder_Result result = KisImageBuilder_RESULT_FAILURE;
00425 QString tmpFile;
00426
00427 if (KIO::NetAccess::download(uri, tmpFile, qApp -> mainWidget())) {
00428 KURL uriTF;
00429 uriTF.setPath( tmpFile );
00430 result = decode(uriTF);
00431 KIO::NetAccess::removeTempFile(tmpFile);
00432 }
00433
00434 return result;
00435 }
00436
00437
00438 KisImageSP KisPNGConverter::image()
00439 {
00440 return m_img;
00441 }
00442
00443
00444 KisImageBuilder_Result KisPNGConverter::buildFile(const KURL& uri, KisPaintLayerSP layer, vKisAnnotationSP_it annotationsStart, vKisAnnotationSP_it annotationsEnd, int compression, bool interlace, bool alpha)
00445 {
00446 kdDebug(41008) << "Start writing PNG File" << endl;
00447 if (!layer)
00448 return KisImageBuilder_RESULT_INVALID_ARG;
00449
00450 KisImageSP img = layer -> image();
00451 if (!img)
00452 return KisImageBuilder_RESULT_EMPTY;
00453
00454 if (uri.isEmpty())
00455 return KisImageBuilder_RESULT_NO_URI;
00456
00457 if (!uri.isLocalFile())
00458 return KisImageBuilder_RESULT_NOT_LOCAL;
00459
00460 FILE *fp = fopen(QFile::encodeName(uri.path()), "wb");
00461 if (!fp)
00462 {
00463 return (KisImageBuilder_RESULT_FAILURE);
00464 }
00465 int height = img->height();
00466 int width = img->width();
00467
00468 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL);
00469 if (!png_ptr)
00470 {
00471 KIO::del(uri);
00472 return (KisImageBuilder_RESULT_FAILURE);
00473 }
00474
00475 png_infop info_ptr = png_create_info_struct(png_ptr);
00476 if (!info_ptr)
00477 {
00478 KIO::del(uri);
00479 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00480 return (KisImageBuilder_RESULT_FAILURE);
00481 }
00482
00483
00484 if (setjmp(png_jmpbuf(png_ptr)))
00485 {
00486 KIO::del(uri);
00487 png_destroy_write_struct(&png_ptr, &info_ptr);
00488 fclose(fp);
00489 return (KisImageBuilder_RESULT_FAILURE);
00490 }
00491
00492 png_init_io(png_ptr, fp);
00493
00494
00495
00496
00497
00498
00499 png_set_compression_level(png_ptr, compression);
00500
00501
00502 png_set_compression_mem_level(png_ptr, 8);
00503 png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
00504 png_set_compression_window_bits(png_ptr, 15);
00505 png_set_compression_method(png_ptr, 8);
00506 png_set_compression_buffer_size(png_ptr, 8192);
00507
00508 int color_nb_bits = 8 * layer->paintDevice()->pixelSize() / layer->paintDevice()->nChannels();
00509 int color_type = getColorTypeforColorSpace(img->colorSpace(), alpha);
00510
00511 if(color_type == -1)
00512 {
00513 return KisImageBuilder_RESULT_UNSUPPORTED;
00514 }
00515
00516 int interlacetype = interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE;
00517
00518 png_set_IHDR(png_ptr, info_ptr,
00519 width,
00520 height,
00521 color_nb_bits,
00522 color_type, interlacetype,
00523 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
00524
00525 png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_ABSOLUTE);
00526
00527
00528 vKisAnnotationSP_it it = annotationsStart;
00529 while(it != annotationsEnd) {
00530 if (!(*it) || (*it) -> type() == QString()) {
00531 kdDebug(41008) << "Warning: empty annotation" << endl;
00532 ++it;
00533 continue;
00534 }
00535
00536 kdDebug(41008) << "Trying to store annotation of type " << (*it) -> type() << " of size " << (*it) -> annotation() . size() << endl;
00537
00538 if ((*it) -> type().startsWith("krita_attribute:")) {
00539
00540 kdDebug(41008) << "can't save this annotation : " << (*it) -> type() << endl;
00541 } else {
00542 char* name = new char[(*it)->type().length()+1];
00543 strcpy(name, (*it)->type().ascii());
00544 png_set_iCCP(png_ptr, info_ptr, name, PNG_COMPRESSION_TYPE_BASE, (char*)(*it)->annotation().data(), (*it) -> annotation() . size());
00545 }
00546 ++it;
00547 }
00548
00549
00550 png_text texts[3];
00551 int nbtexts = 0;
00552 KoDocumentInfo * info = m_doc->documentInfo();
00553 KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(info->page( "about" ));
00554 QString title = aboutPage->title();
00555 if(!title.isEmpty())
00556 {
00557 fillText(texts+nbtexts, "title", title);
00558 nbtexts++;
00559 }
00560 QString abstract = aboutPage->abstract();
00561 if(!abstract.isEmpty())
00562 {
00563 fillText(texts+nbtexts, "abstract", abstract);
00564 nbtexts++;
00565 }
00566 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor *>(info->page( "author" ));
00567 QString author = authorPage->fullName();
00568 if(!author.isEmpty())
00569 {
00570 fillText(texts+nbtexts, "author", author);
00571 nbtexts++;
00572 }
00573
00574 png_set_text(png_ptr, info_ptr, texts, nbtexts);
00575
00576
00577 png_write_info(png_ptr, info_ptr);
00578 png_write_flush(png_ptr);
00579
00580
00581 #ifndef WORDS_BIGENDIAN
00582 if (color_nb_bits > 8 )
00583 png_set_swap(png_ptr);
00584 #endif
00585
00586
00587
00588
00589
00590 png_byte** row_pointers= new png_byte*[height];
00591
00592 for (int y = 0; y < height; y++) {
00593 KisHLineIterator it = layer->paintDevice()->createHLineIterator(0, y, width, false);
00594 row_pointers[y] = new png_byte[width*layer->paintDevice()->pixelSize()];
00595 switch(color_type)
00596 {
00597 case PNG_COLOR_TYPE_GRAY:
00598 case PNG_COLOR_TYPE_GRAY_ALPHA:
00599 if(color_nb_bits == 16)
00600 {
00601 Q_UINT16 *dst = reinterpret_cast<Q_UINT16 *>(row_pointers[y]);
00602 while (!it.isDone()) {
00603 const Q_UINT16 *d = reinterpret_cast<const Q_UINT16 *>(it.rawData());
00604 *(dst++) = d[0];
00605 if(alpha) *(dst++) = d[1];
00606 ++it;
00607 }
00608 } else {
00609 Q_UINT8 *dst = row_pointers[y];
00610 while (!it.isDone()) {
00611 const Q_UINT8 *d = it.rawData();
00612 *(dst++) = d[0];
00613 if(alpha) *(dst++) = d[1];
00614 ++it;
00615 }
00616 }
00617 break;
00618 case PNG_COLOR_TYPE_RGB:
00619 case PNG_COLOR_TYPE_RGB_ALPHA:
00620 if(color_nb_bits == 16)
00621 {
00622 Q_UINT16 *dst = reinterpret_cast<Q_UINT16 *>(row_pointers[y]);
00623 while (!it.isDone()) {
00624 const Q_UINT16 *d = reinterpret_cast<const Q_UINT16 *>(it.rawData());
00625 *(dst++) = d[2];
00626 *(dst++) = d[1];
00627 *(dst++) = d[0];
00628 if(alpha) *(dst++) = d[3];
00629 ++it;
00630 }
00631 } else {
00632 Q_UINT8 *dst = row_pointers[y];
00633 while (!it.isDone()) {
00634 const Q_UINT8 *d = it.rawData();
00635 *(dst++) = d[2];
00636 *(dst++) = d[1];
00637 *(dst++) = d[0];
00638 if(alpha) *(dst++) = d[3];
00639 ++it;
00640 }
00641 }
00642 break;
00643 default:
00644 KIO::del(uri);
00645 return KisImageBuilder_RESULT_UNSUPPORTED;
00646 }
00647 }
00648
00649 png_write_image(png_ptr, row_pointers);
00650
00651
00652 png_write_end(png_ptr, info_ptr);
00653
00654
00655 png_destroy_write_struct(&png_ptr, &info_ptr);
00656 for (int y = 0; y < height; y++) {
00657 delete[] row_pointers[y];
00658 }
00659 delete[] row_pointers;
00660
00661 fclose(fp);
00662
00663 return KisImageBuilder_RESULT_OK;
00664 }
00665
00666
00667 void KisPNGConverter::cancel()
00668 {
00669 m_stop = true;
00670 }
00671
00672 void KisPNGConverter::progress(png_structp png_ptr, png_uint_32 row_number, int pass)
00673 {
00674 if(png_ptr == NULL || row_number > PNG_MAX_UINT || pass > 7) return;
00675
00676 }
00677
00678
00679 #include "kis_png_converter.moc"
00680