Changeset 46931 in webkit


Ignore:
Timestamp:
Aug 7, 2009 5:03:21 PM (15 years ago)
Author:
abarth@webkit.org
Message:

2009-08-07 Nicolas Weber <thakis@chromium.org>

Teach WebKit how to decode jpegs in cmyk and ycck color spaces.
Heavily inspired by Firefox's take on this issue.

https://bugs.webkit.org/show_bug.cgi?id=27909

Reviewed by Eric Seidel.

  • platform/image-decoders/jpeg/JPEGImageDecoder.cpp: (WebCore::JPEGImageReader::decode): Tell jpeglib to convert ycck to cmyk and keep cmyk. (WebCore::convertCMYKToRGBA): Added function to convert cmyk to rgb. (WebCore::convertRGBToRGBA): Extracted existing conversion logic into its own function. (WebCore::JPEGImageDecoder::outputScanlines): Call convertCMYKToRGBA for cmyk images, convertRGBToRGBA for rgb images.
Location:
trunk/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r46925 r46931  
     12009-08-07  Nicolas Weber  <thakis@chromium.org>
     2
     3        Teach WebKit how to decode jpegs in cmyk and ycck color spaces.
     4        Heavily inspired by Firefox's take on this issue.
     5
     6        https://bugs.webkit.org/show_bug.cgi?id=27909
     7
     8        Reviewed by Eric Seidel.
     9
     10        * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
     11        (WebCore::JPEGImageReader::decode):
     12        Tell jpeglib to convert ycck to cmyk and keep cmyk.
     13        (WebCore::convertCMYKToRGBA):
     14        Added function to convert cmyk to rgb.
     15        (WebCore::convertRGBToRGBA):
     16        Extracted existing conversion logic into its own function.
     17        (WebCore::JPEGImageDecoder::outputScanlines):
     18        Call convertCMYKToRGBA for cmyk images, convertRGBToRGBA for rgb
     19        images.
     20
    1212009-08-07  Drew Wilson  <atwilson@google.com>
    222
  • trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp

    r46884 r46931  
    195195                    case JCS_CMYK:
    196196                    case JCS_YCCK:
     197                        // jpeglib cannot convert these to rgb, but it can
     198                        // convert ycck to cmyk
     199                        m_info.out_color_space = JCS_CMYK;
     200                        break;
    197201                    default:
    198202                        m_state = JPEG_ERROR;
     
    458462}
    459463
     464static void convertCMYKToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_struct* info)
     465{
     466    ASSERT(info->out_color_space == JCS_CMYK);
     467
     468    for (unsigned x = 0; x < info->output_width; ++x) {
     469        unsigned c = *src++;
     470        unsigned m = *src++;
     471        unsigned y = *src++;
     472        unsigned k = *src++;
     473
     474        // Source is 'Inverted CMYK', output is RGB.
     475        // See: http://www.easyrgb.com/math.php?MATH=M12#text12
     476        // Or:  http://www.ilkeratalay.com/colorspacesfaq.php#rgb
     477
     478        // From CMYK to CMY
     479        // C = C * ( 1 - K ) + K
     480        // M = M * ( 1 - K ) + K
     481        // Y = Y * ( 1 - K ) + K
     482
     483        // From Inverted CMYK to CMY is thus:
     484        // C = (1-iC) * (1 - (1-iK)) + (1-iK) => 1 - iC*iK
     485        // Same for M and Y
     486
     487        // Convert from CMY (0..1) to RGB (0..1)
     488        // R = 1 - C => 1 - (1 - iC*iK) => iC*iK
     489        // G = 1 - M => 1 - (1 - iM*iK) => iM*iK
     490        // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
     491
     492        // read_scanlines has increased the scanline counter, so we
     493        // actually mean the previous one.
     494        dest.setRGBA(x, info->output_scanline - 1, c * k / 255, m * k / 255, y * k / 255, 0xFF);
     495    }
     496}
     497
     498static void convertRGBToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_struct* info)
     499{
     500    ASSERT(info->out_color_space == JCS_RGB);
     501
     502    for (unsigned x = 0; x < info->output_width; ++x) {
     503        unsigned r = *src++;
     504        unsigned g = *src++;
     505        unsigned b = *src++;
     506        // read_scanlines has increased the scanline counter, so we
     507        // actually mean the previous one.
     508        dest.setRGBA(x, info->output_scanline - 1, r, g, b, 0xFF);
     509    }
     510}
     511
    460512bool JPEGImageDecoder::outputScanlines()
    461513{
     
    484536        if (jpeg_read_scanlines(info, samples, 1) != 1)
    485537            return false;
    486         JSAMPLE *j1 = samples[0];
    487         for (unsigned x = 0; x < info->output_width; ++x) {
    488             unsigned r = *j1++;
    489             unsigned g = *j1++;
    490             unsigned b = *j1++;
    491             // read_scanlines has increased the scanline counter, so we
    492             // actually mean the previous one.
    493             buffer.setRGBA(x, info->output_scanline - 1, r, g, b, 0xFF);
    494         }
     538
     539        if (info->out_color_space == JCS_RGB)
     540            convertRGBToRGBA(buffer, *samples, info);
     541        else if (info->out_color_space == JCS_CMYK)
     542            convertCMYKToRGBA(buffer, *samples, info);
     543        else
     544            return false;
    495545    }
    496546
Note: See TracChangeset for help on using the changeset viewer.