SVN commit 527118 by mwiesweg:
digikam from trunk: Allow reading JPEG files in CMYK color spaces The image data will be converted to RGB in the most simple way as Qt does it. (For full colorspace independence, use Krita.) Fix JPEG loader and thumbnail ioslave. CCMAIL: [hidden email] M +44 -5 kioslave/digikamthumbnail.cpp M +86 -5 libs/dimg/loaders/jpegloader.cpp --- trunk/extragear/graphics/digikam/kioslave/digikamthumbnail.cpp #527117:527118 @@ -491,11 +491,36 @@ cinfo.scale_num=1; cinfo.scale_denom=scale; - // Create QImage + switch (cinfo.jpeg_color_space) + { + case JCS_UNKNOWN: + break; + case JCS_GRAYSCALE: + case JCS_RGB: + case JCS_YCbCr: + cinfo.out_color_space = JCS_RGB; + break; + case JCS_CMYK: + case JCS_YCCK: + cinfo.out_color_space = JCS_CMYK; + break; + } + jpeg_start_decompress(&cinfo); QImage img; + // We only take RGB with 1 or 3 components, or CMYK with 4 components + if (!( + (cinfo.out_color_space == JCS_RGB && (cinfo.output_components == 3 || cinfo.output_components == 1)) + || (cinfo.out_color_space == JCS_CMYK && cinfo.output_components == 4) + )) + { + jpeg_destroy_decompress(&cinfo); + fclose(inputFile); + return false; + } + switch(cinfo.output_components) { case 3: @@ -508,8 +533,6 @@ for (int i=0; i<256; i++) img.setColor(i, qRgb(i,i,i)); break; - default: - return false; } uchar** lines = img.jumpTable(); @@ -519,7 +542,7 @@ jpeg_finish_decompress(&cinfo); // Expand 24->32 bpp - if ( cinfo.output_components == 3 ) + if ( cinfo.output_components == 3 ) { for (uint j=0; j<cinfo.output_height; j++) { @@ -528,12 +551,28 @@ for (uint i=cinfo.output_width; i--; ) { - in-=3; + in -= 3; out[i] = qRgb(in[0], in[1], in[2]); } } } + else if ( cinfo.output_components == 4 ) + { + // CMYK conversion + for (uint j=0; j<cinfo.output_height; j++) + { + uchar *in = img.scanLine(j) + cinfo.output_width*4; + QRgb *out = (QRgb*)( img.scanLine(j) ); + for (uint i=cinfo.output_width; i--; ) + { + in -= 4; + int k = in[3]; + out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255); + } + } + } + int newMax = QMAX(cinfo.output_width, cinfo.output_height); int newx = cachedSize_*cinfo.output_width / newMax; int newy = cachedSize_*cinfo.output_height / newMax; --- trunk/extragear/graphics/digikam/libs/dimg/loaders/jpegloader.cpp #527117:527118 @@ -33,7 +33,7 @@ // This line must be commented to prevent any latency time // when we use threaded image loader interface for each image // files io. Uncomment this line only for debugging. -//#define ENABLE_DEBUG_MESSAGES +//#define ENABLE_DEBUG_MESSAGES // C ansi includes. @@ -161,10 +161,32 @@ // Recording ICC profile marker (from iccjpeg.c) setup_read_icc_profile(&cinfo); + // read image information jpeg_read_header(&cinfo, true); + + // set decompression parameters cinfo.do_fancy_upsampling = false; cinfo.do_block_smoothing = false; - cinfo.out_color_space = JCS_RGB; + // Libjpeg handles the following conversions: + // YCbCr => GRAYSCALE, YCbCr => RGB, GRAYSCALE => RGB, YCCK => CMYK + // So we cannot get RGB from CMYK or YCCK, CMYK conversion is handled below + switch (cinfo.jpeg_color_space) + { + case JCS_UNKNOWN: + // perhaps jpeg_read_header did some guessing, leave value unchanged + break; + case JCS_GRAYSCALE: + case JCS_RGB: + case JCS_YCbCr: + cinfo.out_color_space = JCS_RGB; + break; + case JCS_CMYK: + case JCS_YCCK: + cinfo.out_color_space = JCS_CMYK; + break; + } + + // initialize decompression jpeg_start_decompress(&cinfo); // some pseudo-progress @@ -190,15 +212,24 @@ return false; } - if (cinfo.output_components != 3 && cinfo.output_components != 1) + // We only take RGB with 1 or 3 components, or CMYK with 4 components + if (!( + (cinfo.out_color_space == JCS_RGB && (cinfo.output_components == 3 || cinfo.output_components == 1)) + || (cinfo.out_color_space == JCS_CMYK && cinfo.output_components == 4) + )) { jpeg_destroy_decompress(&cinfo); fclose(file); - kdDebug() << k_funcinfo << "Number of JPEG color components unsupported!" << endl; + kdDebug() << k_funcinfo + << "JPEG colorspace (" + << cinfo.out_color_space + << ") or Number of JPEG color components (" + << cinfo.output_components + << ") unsupported!" << endl; return false; } - data = new uchar[w * 16 * 3]; + data = new uchar[w * 16 * cinfo.output_components]; if (!data) { @@ -314,7 +345,57 @@ } } } + else // CMYK + { + for (i = 0; i < cinfo.rec_outbuf_height; i++) + line[i] = data + (i * w * 4); + int checkPoint = 0; + for (l = 0; l < h; l += cinfo.rec_outbuf_height) + { + // use 0-10% and 90-100% for pseudo-progress + if (observer && l >= checkPoint) + { + checkPoint += granularity(observer, h, 0.8); + if (!observer->continueQuery(m_image)) + { + delete [] data; + delete [] dest; + jpeg_destroy_decompress(&cinfo); + fclose(file); + return false; + } + observer->progressInfo(m_image, 0.1 + (0.8 * ( ((float)l)/((float)h) ))); + } + + jpeg_read_scanlines(&cinfo, &line[0], cinfo.rec_outbuf_height); + scans = cinfo.rec_outbuf_height; + + if ((h - l) < scans) + scans = h - l; + + ptr = data; + + for (y = 0; y < scans; y++) + { + for (x = 0; x < w; x++) + { + // Inspired by Qt's JPEG loader + + int k = ptr[3]; + + ptr2[3] = 0xFF; + ptr2[2] = k * ptr[0] / 255; + ptr2[1] = k * ptr[1] / 255; + ptr2[0] = k * ptr[2] / 255; + + ptr += 4; + ptr2 += 4; + } + } + } + } + delete [] data; // ------------------------------------------------------------------- _______________________________________________ Digikam-devel mailing list [hidden email] https://mail.kde.org/mailman/listinfo/digikam-devel |
Free forum by Nabble | Edit this page |