Source/WebCore: [chromium] Add iccjpeg and qcms to chromium port
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Jun 2012 02:53:17 +0000 (02:53 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Jun 2012 02:53:17 +0000 (02:53 +0000)
       https://bugs.webkit.org/show_bug.cgi?id=81974

       Reviewed by Adam Barth.

       Covered by existing layout tests which will be rebaselined.

       * WebCore.gyp/WebCore.gyp: Add qcms to the build.
       * platform/image-decoders/ImageDecoder.h:
       (WebCore::ImageDecoder::qcmsOutputDeviceProfile): Return an sRGB profile.
       On OSX, return the default RGB profile. Add FIXME to use the user's
       monitor profile and verify that profile for other platforms.

       * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
       (turboSwizzled): For libjpeg-turbo, JCS_EXT_BGRA and JCS_EXT_RGBA are the
       two known output color spaces for which the decoder uses a data swizzle.
       (colorSpaceHasAlpha): JPEG's have no alpha in the output color space. For
       libjpeg-turbo, alpha may be present in the swizzled output color space.

       (WebCore::JPEGImageReader::JPEGImageReader):
       (WebCore::JPEGImageReader::close):
       (WebCore::JPEGImageReader::decode): For QCMSLIB, create the color transform
       to use during decoding, and ensure we switch to inputing RGBA data to qcms
       even if the desired output data is BGRA: outputScanlines() sends BGRA data
       to the frame buffer following color correction if needed.
       (JPEGImageReader):
       (WebCore::JPEGImageReader::colorTransform): qcms color transform getter.
       (WebCore::JPEGImageReader::createColorTransform): Create color transform.
       Release the existing transform (if any) and assign to the color transform
       created from the color profile data.
       (WebCore::JPEGImageDecoder::outputScanlines): Minor style fix. Apply color
       transform to each decoded image row.

       * platform/image-decoders/png/PNGImageDecoder.cpp:
       (WebCore::PNGImageReader::PNGImageReader):
       (WebCore::PNGImageReader::close):
       (WebCore::PNGImageReader::currentBufferSize): Move this adjacent to other
       setters and getters.
       (WebCore::PNGImageReader::decodingSizeOnly): Ditto.
       (WebCore::PNGImageReader::setHasAlpha): Ditto.
       (WebCore::PNGImageReader::hasAlpha): Ditto.
       (WebCore::PNGImageReader::interlaceBuffer): Ditto.
       (WebCore::PNGImageReader::createRowBuffer): Creates a temporary row buffer,
       used when a color transform is applied to the decoded image pixels.
       (WebCore::PNGImageReader::rowBuffer): Return the temporary row buffer.
       (WebCore::PNGImageReader::colorTransform): qcms color transform getter.
       (WebCore::PNGImageReader::createColorTransform): Create color transform.
       Release the existing transform (if any) and assign to the color transform
       created from the color profile data.
       (WebCore::PNGImageDecoder::headerAvailable): For QCMSLIB, create the color
       transform to use for decoding. Clear m_colorProfile (not used anymore).
       (WebCore::PNGImageDecoder::rowAvailable): Create temporary row buffer if
       a color transform is needed for decoding. Apply color transform to each
       decoded image row.

       * platform/image-decoders/skia/ImageDecoderSkia.cpp:
       (WebCore::ImageFrame::setColorProfile): Old method of colorProfiles is no
       longer used. Add a FIXME to remove the old implementation.
       (WebCore::ImageFrame::setStatus): Remove old color correction code.

Patch by Tony Payne <tpayne@chromium.org> on 2012-06-14

Source/WTF: [chromium] Add iccjpeg and qcms to chromium port.
https://bugs.webkit.org/show_bug.cgi?id=81974

Patch by Tony Payne <tpayne@chromium.org> on 2012-06-14

* wtf/Platform.h: Add Chromium USE defines for ICCJPEG and QCMSLIB
to each Chromium platform, excluding Android.

Reviewed by Adam Barth.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@120393 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/platform/chromium/TestExpectations
Source/WTF/ChangeLog
Source/WTF/wtf/Platform.h
Source/WebCore/ChangeLog
Source/WebCore/WebCore.gyp/WebCore.gyp
Source/WebCore/platform/image-decoders/ImageDecoder.h
Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp

index bc2eb5b..59adb85 100644 (file)
@@ -1174,10 +1174,6 @@ BUGCR11153 LINUX WIN : platform/chromium/virtual/gpu/fast/canvas/canvas-incremen
 // test_shell, DRT do not correctly schedule paints when invalidating.
 BUGCR62433 WIN : fast/images/gif-loop-count.html = IMAGE
 
-// Implement color profile support.
-BUGCR143 : fast/images/jpeg-with-color-profile.html = MISSING
-BUGCR143 : fast/images/png-with-color-profile.html = MISSING
-
 // -----------------------------------------------------------------
 // SVG TESTS
 // -----------------------------------------------------------------
@@ -3537,6 +3533,98 @@ BUGWK85120 : fast/js/toString-number.html = TEXT
 
 BUGWK68744 : fast/block/float/float-not-removed-from-next-sibling4.html = IMAGE
 
+// Needs to be rebaselined.
+BUGWK87761 MAC LINUX WIN : compositing/color-matching/image-color-matching.html = IMAGE
+BUGWK87761 MAC : compositing/masks/direct-image-mask.html = IMAGE
+BUGWK87761 MAC : compositing/reflections/simple-composited-reflections.html = IMAGE
+BUGWK87761 MAC : compositing/visibility/visibility-image-layers.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/crash-filter-change.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/crash-hw-sw-switch.html = IMAGE
+BUGWK87761 LINUX : css3/filters/custom/custom-filter-shader-cache.html = IMAGE
+BUGWK87761 MAC : css3/filters/custom/effect-color-check.html = IMAGE
+BUGWK87761 LINUX : css3/filters/custom/effect-custom-combined-missing.html = IMAGE
+BUGWK87761 LINUX : css3/filters/custom/effect-custom.html = IMAGE
+BUGWK87761 MAC LINUX : css3/filters/custom/missing-custom-filter-shader.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-blur-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-blur.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-brightness-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-brightness.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-combined-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-combined.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-contrast-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-contrast.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-drop-shadow-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-drop-shadow.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-grayscale-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-grayscale.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-hue-rotate-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-hue-rotate.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-invert-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-invert.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-opacity-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-opacity.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-saturate-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-saturate.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-sepia-hw.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/effect-sepia.html = IMAGE
+BUGWK87761 MAC LINUX WIN : css3/filters/regions-expanding.html = IMAGE
+BUGWK87761 MAC : fast/css/background-shorthand-invalid-url.html = IMAGE
+BUGWK87761 MAC : fast/css/color-correction-on-backgrounds.html = IMAGE
+BUGWK87761 MAC : fast/css/color-correction.html = IMAGE
+BUGWK87761 MAC : fast/images/color-jpeg-with-color-profile.html = IMAGE
+BUGWK87761 MAC : fast/media/mq-min-pixel-ratio.html = IMAGE
+BUGWK87761 MAC : fast/reflections/reflection-direction.html = IMAGE
+BUGWK87761 MAC : fast/reflections/reflection-masks-opacity.html = IMAGE
+BUGWK87761 MAC : fast/reflections/reflection-with-zoom.html = IMAGE
+// There is already an entry for MAC DEBUG
+BUGWK87761 MAC RELEASE : fast/reflections/reflection-masks-outset.html = IMAGE
+BUGWK87761 MAC : fast/reflections/reflection-masks.html = IMAGE
+BUGWK87761 MAC LINUX : http/tests/local/file-url-sent-as-referer.html = IMAGE
+BUGWK87761 MAC : platform/chromium/virtual/threaded/compositing/visibility/visibility-image-layers.html = IMAGE
+BUGWK87761 MAC LINUX : scrollbars/listbox-scrollbar-combinations.html = IMAGE
+BUGWK87761 MAC LINUX : scrollbars/overflow-scrollbar-combinations.html = IMAGE
+BUGWK87761 LINUX : svg/as-border-image/svg-as-border-image.html = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/createImageElement.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/createImageElement2.xhtml = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/focus-ring.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/group-opacity.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/image-parent-translation.xhtml = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/image-small-width-height.svg = IMAGE
+BUGWK87761 MAC : svg/custom/image-with-transform-clip-filter.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/js-update-image-and-display.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/js-update-image-and-display2.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/js-update-image-and-display3.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/js-update-image.svg = IMAGE
+BUGWK87761 MAC : svg/custom/pointer-events-image-css-transform.svg = IMAGE
+BUGWK87761 MAC : svg/custom/pointer-events-image.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/text-image-opacity.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/custom/use-on-g-containing-foreignObject-and-image.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-dom-height-attr.html = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-dom-preserveAspectRatio-attr.html = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-dom-width-attr.html = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-dom-x-attr.html = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-dom-y-attr.html = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-svgdom-height-prop.html = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-svgdom-preserveAspectRatio-prop.html = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-svgdom-width-prop.html = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-svgdom-x-prop.html = IMAGE
+BUGWK87761 MAC LINUX : svg/dynamic-updates/SVGImageElement-svgdom-y-prop.html = IMAGE
+BUGWK87761 MAC LINUX : svg/filters/feImage-subregions-preseveAspectRatio-none-with-viewBox.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/filters/feImage-subregions-preseveAspectRatio-none.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/filters/feImage-subregions.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/filters/filter-source-position.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/repaint/image-href-change.svg = IMAGE
+BUGWK87761 MAC LINUX : svg/transforms/animated-path-inside-transformed-html.xhtml = IMAGE
+BUGWK87761 MAC : svg/wicd/test-rightsizing-b.xhtml = IMAGE
+BUGWK87761 MAC LINUX : svg/zoom/page/zoom-background-images.html = IMAGE
+BUGWK87761 MAC LINUX : svg/zoom/page/zoom-svg-through-object-with-absolute-size-2.xhtml = IMAGE
+BUGWK87761 MAC LINUX : svg/zoom/page/zoom-svg-through-object-with-absolute-size.xhtml = IMAGE
+BUGWK87761 MAC LINUX : svg/zoom/page/zoom-svg-through-object-with-percentage-size.xhtml = IMAGE
+BUGWK87761 MAC : tables/mozilla/bugs/bug82946-2.html = IMAGE
+BUGWK87761 MAC LINUX WIN : fast/images/jpeg-with-color-profile.html = MISSING
+BUGWK87761 MAC LINUX WIN : fast/images/png-with-color-profile.html = MISSING
+
+
 BUGWK83076 SNOWLEOPARD RELEASE : compositing/geometry/outline-change.html = TIMEOUT PASS
 BUGWK83076 SNOWLEOPARD RELEASE : css3/selectors3/xml/css3-modsel-161.xml = TIMEOUT PASS
 BUGWK83076 SNOWLEOPARD RELEASE : css3/selectors3/xml/css3-modsel-166.xml = TIMEOUT PASS
index 1954112..21b03ee 100644 (file)
@@ -1,3 +1,13 @@
+2012-06-14  Tony Payne  <tpayne@chromium.org>
+
+        [chromium] Add iccjpeg and qcms to chromium port.
+        https://bugs.webkit.org/show_bug.cgi?id=81974
+
+        * wtf/Platform.h: Add Chromium USE defines for ICCJPEG and QCMSLIB
+        to each Chromium platform, excluding Android.
+
+        Reviewed by Adam Barth.
+
 2012-06-14  Yong Li  <yoli@rim.com>
 
         [BlackBerry] Implement computeRAMSize for QNX
index 51a87b2..2bc58f3 100644 (file)
 /* USE(SKIA) for Win/Linux/Mac/Android */
 #if PLATFORM(CHROMIUM)
 #if OS(DARWIN)
-#if USE(SKIA_ON_MAC_CHROMIUM)
 #define WTF_USE_SKIA 1
-#else
-#define WTF_USE_CG 1
-#endif
 #define WTF_USE_ATSUI 1
 #define WTF_USE_CORE_TEXT 1
 #define WTF_USE_ICCJPEG 1
+#define WTF_USE_QCMSLIB 1
 #elif OS(ANDROID)
 #define WTF_USE_SKIA 1
 #else
 #define WTF_USE_SKIA 1
 #define WTF_USE_CHROMIUM_NET 1
+#define WTF_USE_ICCJPEG 1
+#define WTF_USE_QCMSLIB 1
 #endif
 #endif
 
index 0142b91..5780ddd 100644 (file)
@@ -1,3 +1,65 @@
+2012-06-14  Tony Payne  <tpayne@chromium.org>
+
+       [chromium] Add iccjpeg and qcms to chromium port
+       https://bugs.webkit.org/show_bug.cgi?id=81974
+
+       Reviewed by Adam Barth.
+
+       Covered by existing layout tests which will be rebaselined.
+
+       * WebCore.gyp/WebCore.gyp: Add qcms to the build.
+       * platform/image-decoders/ImageDecoder.h:
+       (WebCore::ImageDecoder::qcmsOutputDeviceProfile): Return an sRGB profile.
+       On OSX, return the default RGB profile. Add FIXME to use the user's
+       monitor profile and verify that profile for other platforms.
+
+       * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
+       (turboSwizzled): For libjpeg-turbo, JCS_EXT_BGRA and JCS_EXT_RGBA are the
+       two known output color spaces for which the decoder uses a data swizzle.
+       (colorSpaceHasAlpha): JPEG's have no alpha in the output color space. For
+       libjpeg-turbo, alpha may be present in the swizzled output color space.
+
+       (WebCore::JPEGImageReader::JPEGImageReader):
+       (WebCore::JPEGImageReader::close):
+       (WebCore::JPEGImageReader::decode): For QCMSLIB, create the color transform
+       to use during decoding, and ensure we switch to inputing RGBA data to qcms
+       even if the desired output data is BGRA: outputScanlines() sends BGRA data
+       to the frame buffer following color correction if needed.
+       (JPEGImageReader):
+       (WebCore::JPEGImageReader::colorTransform): qcms color transform getter.
+       (WebCore::JPEGImageReader::createColorTransform): Create color transform.
+       Release the existing transform (if any) and assign to the color transform
+       created from the color profile data.
+       (WebCore::JPEGImageDecoder::outputScanlines): Minor style fix. Apply color
+       transform to each decoded image row.
+
+       * platform/image-decoders/png/PNGImageDecoder.cpp:
+       (WebCore::PNGImageReader::PNGImageReader):
+       (WebCore::PNGImageReader::close):
+       (WebCore::PNGImageReader::currentBufferSize): Move this adjacent to other
+       setters and getters.
+       (WebCore::PNGImageReader::decodingSizeOnly): Ditto.
+       (WebCore::PNGImageReader::setHasAlpha): Ditto.
+       (WebCore::PNGImageReader::hasAlpha): Ditto.
+       (WebCore::PNGImageReader::interlaceBuffer): Ditto.
+       (WebCore::PNGImageReader::createRowBuffer): Creates a temporary row buffer,
+       used when a color transform is applied to the decoded image pixels.
+       (WebCore::PNGImageReader::rowBuffer): Return the temporary row buffer.
+       (WebCore::PNGImageReader::colorTransform): qcms color transform getter.
+       (WebCore::PNGImageReader::createColorTransform): Create color transform.
+       Release the existing transform (if any) and assign to the color transform
+       created from the color profile data.
+       (WebCore::PNGImageDecoder::headerAvailable): For QCMSLIB, create the color
+       transform to use for decoding. Clear m_colorProfile (not used anymore).
+       (WebCore::PNGImageDecoder::rowAvailable): Create temporary row buffer if
+       a color transform is needed for decoding. Apply color transform to each
+       decoded image row.
+
+       * platform/image-decoders/skia/ImageDecoderSkia.cpp:
+       (WebCore::ImageFrame::setColorProfile): Old method of colorProfiles is no
+       longer used. Add a FIXME to remove the old implementation.
+       (WebCore::ImageFrame::setStatus): Remove old color correction code.
+
 2012-06-14  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r120384.
index 7d8f957..d95f4cd 100644 (file)
         '<(chromium_src_dir)/third_party/libxslt/libxslt.gyp:libxslt',
         '<(chromium_src_dir)/third_party/libwebp/libwebp.gyp:libwebp',
         '<(chromium_src_dir)/third_party/npapi/npapi.gyp:npapi',
+        '<(chromium_src_dir)/third_party/qcms/qcms.gyp:qcms',
         '<(chromium_src_dir)/third_party/sqlite/sqlite.gyp:sqlite',
         '<(chromium_src_dir)/v8/tools/gyp/v8.gyp:v8',
         '<(libjpeg_gyp_path):libjpeg',
         '<(chromium_src_dir)/third_party/libxslt/libxslt.gyp:libxslt',
         '<(chromium_src_dir)/third_party/npapi/npapi.gyp:npapi',
         '<(chromium_src_dir)/third_party/ots/ots.gyp:ots',
+        '<(chromium_src_dir)/third_party/qcms/qcms.gyp:qcms',
         '<(chromium_src_dir)/third_party/sqlite/sqlite.gyp:sqlite',
         '<(chromium_src_dir)/third_party/angle/src/build_angle.gyp:translator_glsl',
         '<(chromium_src_dir)/third_party/zlib/zlib.gyp:zlib',
         '<(chromium_src_dir)/third_party/libxslt/libxslt.gyp:libxslt',
         '<(chromium_src_dir)/third_party/npapi/npapi.gyp:npapi',
         '<(chromium_src_dir)/third_party/ots/ots.gyp:ots',
+        '<(chromium_src_dir)/third_party/qcms/qcms.gyp:qcms',
         '<(chromium_src_dir)/third_party/sqlite/sqlite.gyp:sqlite',
         '<(chromium_src_dir)/third_party/angle/src/build_angle.gyp:translator_glsl',
         '<(chromium_src_dir)/third_party/zlib/zlib.gyp:zlib',
         '<(chromium_src_dir)/build/temp_gyp/googleurl.gyp:googleurl',
         '<(chromium_src_dir)/skia/skia.gyp:skia',
         '<(chromium_src_dir)/third_party/npapi/npapi.gyp:npapi',
+        '<(chromium_src_dir)/third_party/qcms/qcms.gyp:qcms',
         '<(chromium_src_dir)/v8/tools/gyp/v8.gyp:v8',
       ],
       'export_dependent_settings': [
         '<(chromium_src_dir)/build/temp_gyp/googleurl.gyp:googleurl',
         '<(chromium_src_dir)/skia/skia.gyp:skia',
         '<(chromium_src_dir)/third_party/npapi/npapi.gyp:npapi',
+        '<(chromium_src_dir)/third_party/qcms/qcms.gyp:qcms',
         '<(chromium_src_dir)/v8/tools/gyp/v8.gyp:v8',
       ],
       'direct_dependent_settings': {
index a6bc188..57a5e8a 100644 (file)
 #include "SkColorPriv.h"
 #endif
 
+#if USE(QCMSLIB)
+#include "qcms.h"
+#include <wtf/MainThread.h>
+#if OS(DARWIN)
+#include "GraphicsContextCG.h"
+#include <CoreGraphics/CGColorSpace.h>
+#include <CoreGraphics/CGDirectDisplay.h>
+#include <CoreGraphics/CGDisplayConfiguration.h>
+#include <wtf/RetainPtr.h>
+#endif
+#endif
+
 namespace WebCore {
 
     typedef Vector<char> ColorProfile;
@@ -165,14 +177,12 @@ namespace WebCore {
 
 #if USE(SKIA)
         NativeImageSkia m_bitmap;
-#if PLATFORM(CHROMIUM) && OS(DARWIN)
-        ColorProfile m_colorProfile;
-#endif
 #else
         Vector<PixelData> m_backingStore;
         PixelData* m_bytes; // The memory is backed by m_backingStore.
         IntSize m_size;
         bool m_hasAlpha;
+        // FIXME: Do we need m_colorProfile anymore?
         ColorProfile m_colorProfile;
 #endif
         IntRect m_originalFrameRect; // This will always just be the entire
@@ -289,6 +299,42 @@ namespace WebCore {
             return !memcmp(&profileData[12], "mntr", 4) || !memcmp(&profileData[12], "scnr", 4);
         }
 
+#if USE(QCMSLIB)
+        static qcms_profile* qcmsOutputDeviceProfile()
+        {
+            static qcms_profile* outputDeviceProfile = 0;
+
+            static bool qcmsInitialized = false;
+            if (!qcmsInitialized) {
+                ASSERT(isMainThread());
+                qcmsInitialized = true;
+                // FIXME: Add optional ICCv4 support.
+#if OS(DARWIN)
+                RetainPtr<CGColorSpaceRef> monitorColorSpace(AdoptCF, CGDisplayCopyColorSpace(CGMainDisplayID()));
+                CFDataRef iccProfile(CGColorSpaceCopyICCProfile(monitorColorSpace.get()));
+                if (iccProfile) {
+                    size_t length = CFDataGetLength(iccProfile);
+                    const unsigned char* systemProfile = CFDataGetBytePtr(iccProfile);
+                    outputDeviceProfile = qcms_profile_from_memory(systemProfile, length);
+                    if (outputDeviceProfile && qcms_profile_is_bogus(outputDeviceProfile)) {
+                        qcms_profile_release(outputDeviceProfile);
+                        outputDeviceProfile = 0;
+                    }
+                }
+                if (!outputDeviceProfile)
+                    outputDeviceProfile = qcms_profile_sRGB();
+#else
+                // FIXME: sRGB profiles don't add much value. Use the user's monitor profile.
+                outputDeviceProfile = qcms_profile_sRGB();
+#endif
+                // FIXME: Check that the profile is valid. Fallback to sRGB if not?
+                if (outputDeviceProfile)
+                    qcms_profile_precache_output_transform(outputDeviceProfile);
+            }
+            return outputDeviceProfile;
+        }
+#endif
+
         // Sets the "decode failure" flag.  For caller convenience (since so
         // many callers want to return false after calling this), returns false
         // to enable easy tailcalling.  Subclasses may override this to also
@@ -320,6 +366,7 @@ namespace WebCore {
 
         RefPtr<SharedBuffer> m_data; // The encoded data.
         Vector<ImageFrame> m_frameBufferCache;
+        // FIXME: Do we need m_colorProfile any more, for any port?
         ColorProfile m_colorProfile;
         bool m_scaled;
         Vector<int> m_scaledColumns;
index 46a28ba..ec8de28 100644 (file)
@@ -60,6 +60,9 @@ extern "C" {
 #if USE(ICCJPEG)
 #include "iccjpeg.h"
 #endif
+#if USE(QCMSLIB)
+#include "qcms.h"
+#endif
 #include <setjmp.h>
 }
 
@@ -76,9 +79,11 @@ inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_RGBA; }
 #else
 inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_BGRA; }
 #endif
-inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { return colorSpace == rgbOutputColorSpace(); }
+inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { return colorSpace == JCS_EXT_RGBA || colorSpace == JCS_EXT_BGRA; }
+inline bool colorSpaceHasAlpha(J_COLOR_SPACE colorSpace) { return turboSwizzled(colorSpace); }
 #else
 inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_RGB; }
+inline bool colorSpaceHasAlpha(J_COLOR_SPACE) { return false; }
 #endif
 
 #if OS(ANDROID)
@@ -163,6 +168,9 @@ public:
         , m_bytesToSkip(0)
         , m_state(JPEG_HEADER)
         , m_samples(0)
+#if USE(QCMSLIB)
+        , m_transform(0)
+#endif
     {
         memset(&m_info, 0, sizeof(jpeg_decompress_struct));
 
@@ -210,6 +218,11 @@ public:
             fastFree(src);
         m_info.src = 0;
 
+#if USE(QCMSLIB)
+        if (m_transform)
+            qcms_transform_release(m_transform);
+        m_transform = 0;
+#endif
         jpeg_destroy_decompress(&m_info);
     }
 
@@ -298,6 +311,14 @@ public:
                 ColorProfile rgbInputDeviceColorProfile = readColorProfile(info());
                 if (!rgbInputDeviceColorProfile.isEmpty())
                     m_decoder->setColorProfile(rgbInputDeviceColorProfile);
+#if USE(QCMSLIB)
+                createColorTransform(rgbInputDeviceColorProfile, colorSpaceHasAlpha(m_info.out_color_space));
+#if defined(TURBO_JPEG_RGB_SWIZZLE)
+                // Input RGBA data to qcms. Note: restored to BGRA on output.
+                if (m_transform && m_info.out_color_space == JCS_EXT_BGRA)
+                    m_info.out_color_space = JCS_EXT_RGBA;
+#endif
+#endif
             }
 
             if (m_decodingSizeOnly) {
@@ -402,6 +423,31 @@ public:
     jpeg_decompress_struct* info() { return &m_info; }
     JSAMPARRAY samples() const { return m_samples; }
     JPEGImageDecoder* decoder() { return m_decoder; }
+#if USE(QCMSLIB)
+    qcms_transform* colorTransform() const { return m_transform; }
+
+    void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha)
+    {
+        if (m_transform)
+            qcms_transform_release(m_transform);
+        m_transform = 0;
+
+        if (colorProfile.isEmpty())
+            return;
+        qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile();
+        if (!deviceProfile)
+            return;
+        qcms_profile* inputProfile = qcms_profile_from_memory(colorProfile.data(), colorProfile.size());
+        if (!inputProfile)
+            return;
+        // We currently only support color profiles for RGB profiled images.
+        ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile));
+        qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8;
+        // FIXME: Don't force perceptual intent if the image profile contains an intent.
+        m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProfile, dataFormat, QCMS_INTENT_PERCEPTUAL);
+        qcms_profile_release(inputProfile);
+    }
+#endif
 
 private:
     JPEGImageDecoder* m_decoder;
@@ -414,6 +460,10 @@ private:
     jstate m_state;
 
     JSAMPARRAY m_samples;
+
+#if USE(QCMSLIB)
+    qcms_transform* m_transform;
+#endif
 };
 
 // Override the standard error method in the IJG JPEG decoder code.
@@ -521,11 +571,15 @@ bool JPEGImageDecoder::outputScanlines()
 
 #if !ENABLE(IMAGE_DECODER_DOWN_SAMPLING) && defined(TURBO_JPEG_RGB_SWIZZLE)
     if (turboSwizzled(info->out_color_space)) {
-         ASSERT(!m_scaled);
-         while (info->output_scanline < info->output_height) {
-             unsigned char* row = reinterpret_cast<unsigned char*>(buffer.getAddr(0, info->output_scanline));
-             if (jpeg_read_scanlines(info, &row, 1) != 1)
-                  return false;
+        ASSERT(!m_scaled);
+        while (info->output_scanline < info->output_height) {
+            unsigned char* row = reinterpret_cast<unsigned char*>(buffer.getAddr(0, info->output_scanline));
+            if (jpeg_read_scanlines(info, &row, 1) != 1)
+                return false;
+#if USE(QCMSLIB)
+            if (qcms_transform* transform = m_reader->colorTransform())
+                qcms_transform_data_type(transform, row, row, info->output_width, rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX);
+#endif
          }
          return true;
      }
@@ -544,6 +598,10 @@ bool JPEGImageDecoder::outputScanlines()
         int destY = scaledY(sourceY);
         if (destY < 0)
             continue;
+#if USE(QCMSLIB)
+        if (m_reader->colorTransform() && info->out_color_space == JCS_RGB)
+            qcms_transform_data(m_reader->colorTransform(), *samples, *samples, info->output_width);
+#endif
         int width = m_scaled ? m_scaledColumns.size() : info->output_width;
         for (int x = 0; x < width; ++x) {
             JSAMPLE* jsample = *samples + (m_scaled ? m_scaledColumns[x] : x) * ((info->out_color_space == JCS_RGB) ? 3 : 4);
index 815b096..138d5c5 100644 (file)
 #include "PNGImageDecoder.h"
 
 #include "png.h"
+#include <wtf/OwnArrayPtr.h>
 #include <wtf/PassOwnPtr.h>
 
 #if PLATFORM(CHROMIUM)
 #include "TraceEvent.h"
 #endif
 
+#if USE(QCMSLIB)
+#include "qcms.h"
+#endif
+
 #if defined(PNG_LIBPNG_VER_MAJOR) && defined(PNG_LIBPNG_VER_MINOR) && (PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 4))
 #define JMPBUF(png_ptr) png_jmpbuf(png_ptr)
 #else
@@ -107,10 +112,14 @@ class PNGImageReader
 public:
     PNGImageReader(PNGImageDecoder* decoder)
         : m_readOffset(0)
+        , m_currentBufferSize(0)
         , m_decodingSizeOnly(false)
-        , m_interlaceBuffer(0)
         , m_hasAlpha(false)
-        , m_currentBufferSize(0)
+        , m_interlaceBuffer(0)
+#if USE(QCMSLIB)
+        , m_transform(0)
+        , m_rowBuffer()
+#endif
     {
         m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, decodingFailed, decodingWarning);
         m_info = png_create_info_struct(m_png);
@@ -127,13 +136,16 @@ public:
         if (m_png && m_info)
             // This will zero the pointers.
             png_destroy_read_struct(&m_png, &m_info, 0);
+#if USE(QCMSLIB)
+        if (m_transform)
+            qcms_transform_release(m_transform);
+        m_transform = 0;
+#endif
         delete[] m_interlaceBuffer;
         m_interlaceBuffer = 0;
         m_readOffset = 0;
     }
 
-    unsigned currentBufferSize() const { return m_currentBufferSize; }
-
     bool decode(const SharedBuffer& data, bool sizeOnly)
     {
         m_decodingSizeOnly = sizeOnly;
@@ -157,25 +169,57 @@ public:
         return false;
     }
 
-    bool decodingSizeOnly() const { return m_decodingSizeOnly; }
     png_structp pngPtr() const { return m_png; }
     png_infop infoPtr() const { return m_info; }
-    png_bytep interlaceBuffer() const { return m_interlaceBuffer; }
-    bool hasAlpha() const { return m_hasAlpha; }
 
     void setReadOffset(unsigned offset) { m_readOffset = offset; }
-    void setHasAlpha(bool b) { m_hasAlpha = b; }
+    unsigned currentBufferSize() const { return m_currentBufferSize; }
+    bool decodingSizeOnly() const { return m_decodingSizeOnly; }
+    void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; }
+    bool hasAlpha() const { return m_hasAlpha; }
 
+    png_bytep interlaceBuffer() const { return m_interlaceBuffer; }
     void createInterlaceBuffer(int size) { m_interlaceBuffer = new png_byte[size]; }
+#if USE(QCMSLIB)
+    png_bytep rowBuffer() const { return m_rowBuffer.get(); }
+    void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[size]); }
+    qcms_transform* colorTransform() const { return m_transform; }
+
+    void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha)
+    {
+        if (m_transform)
+            qcms_transform_release(m_transform);
+        m_transform = 0;
+
+        if (colorProfile.isEmpty())
+            return;
+        qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile();
+        if (!deviceProfile)
+            return;
+        qcms_profile* inputProfile = qcms_profile_from_memory(colorProfile.data(), colorProfile.size());
+        if (!inputProfile)
+            return;
+        // We currently only support color profiles for RGB and RGBA images.
+        ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile));
+        qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8;
+        // FIXME: Don't force perceptual intent if the image profile contains an intent.
+        m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProfile, dataFormat, QCMS_INTENT_PERCEPTUAL);
+        qcms_profile_release(inputProfile);
+    }
+#endif
 
 private:
-    unsigned m_readOffset;
-    bool m_decodingSizeOnly;
     png_structp m_png;
     png_infop m_info;
-    png_bytep m_interlaceBuffer;
-    bool m_hasAlpha;
+    unsigned m_readOffset;
     unsigned m_currentBufferSize;
+    bool m_decodingSizeOnly;
+    bool m_hasAlpha;
+    png_bytep m_interlaceBuffer;
+#if USE(QCMSLIB)
+    qcms_transform* m_transform;
+    OwnArrayPtr<png_byte> m_rowBuffer;
+#endif
 };
 
 PNGImageDecoder::PNGImageDecoder(ImageSource::AlphaOption alphaOption,
@@ -298,6 +342,10 @@ void PNGImageDecoder::headerAvailable()
         // the color profile or we'd need to decode into a gray-scale image buffer and
         // hand that to CoreGraphics.
         readColorProfile(png, info, m_colorProfile);
+#if USE(QCMSLIB)
+        m_reader->createColorTransform(m_colorProfile, colorType & PNG_COLOR_MASK_ALPHA);
+        m_colorProfile.clear();
+#endif
     }
 
     // The options we set here match what Mozilla does.
@@ -367,8 +415,8 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
             return;
         }
 
+        unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3;
         if (PNG_INTERLACE_ADAM7 == png_get_interlace_type(png, m_reader->infoPtr())) {
-            unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3;
             m_reader->createInterlaceBuffer(colorChannels * size().width() * size().height());
             if (!m_reader->interlaceBuffer()) {
                 longjmp(JMPBUF(png), 1);
@@ -376,6 +424,15 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
             }
         }
 
+#if USE(QCMSLIB)
+        if (m_reader->colorTransform()) {
+            m_reader->createRowBuffer(colorChannels * size().width());
+            if (!m_reader->rowBuffer()) {
+                longjmp(JMPBUF(png), 1);
+                return;
+            }
+        }
+#endif
         buffer.setStatus(ImageFrame::FramePartial);
         buffer.setHasAlpha(false);
         buffer.setColorProfile(m_colorProfile);
@@ -433,6 +490,13 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
         png_progressive_combine_row(m_reader->pngPtr(), row, rowBuffer);
     }
 
+#if USE(QCMSLIB)
+    if (qcms_transform* transform = m_reader->colorTransform()) {
+        qcms_transform_data(transform, row, m_reader->rowBuffer(), size().width());
+        row = m_reader->rowBuffer();
+    }
+#endif
+
     // Write the decoded row pixels to the frame buffer.
     int width = scaledSize().width();
     bool nonTrivialAlpha = false;
index d2f06d9..5cc132c 100644 (file)
 #include "config.h"
 #include "ImageDecoder.h"
 
-#include "NotImplemented.h"
-
-#if PLATFORM(CHROMIUM) && OS(DARWIN)
-#include "GraphicsContextCG.h"
-#include "SkCGUtils.h"
-#endif
-
 namespace WebCore {
 
 ImageFrame::ImageFrame()
@@ -114,58 +107,17 @@ void ImageFrame::setHasAlpha(bool alpha)
     m_bitmap.bitmap().setIsOpaque(!alpha);
 }
 
-#if PLATFORM(CHROMIUM) && OS(DARWIN)
-static void resolveColorSpace(const SkBitmap& bitmap, CGColorSpaceRef colorSpace)
-{
-    int width = bitmap.width();
-    int height = bitmap.height();
-    RetainPtr<CGImageRef> srcImage(AdoptCF, SkCreateCGImageRefWithColorspace(bitmap, colorSpace));
-    SkAutoLockPixels lock(bitmap);
-    void* pixels = bitmap.getPixels();
-    RetainPtr<CGContextRef> cgBitmap(AdoptCF, CGBitmapContextCreate(pixels, width, height, 8, width * 4, deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst));
-    if (!cgBitmap)
-        return;
-    CGContextSetBlendMode(cgBitmap.get(), kCGBlendModeCopy);
-    CGRect bounds = { {0, 0}, {width, height} };
-    CGContextDrawImage(cgBitmap.get(), bounds, srcImage.get());
-}
-
-static CGColorSpaceRef createColorSpace(const ColorProfile& colorProfile)
-{
-    RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(colorProfile.data()), colorProfile.size()));
-#ifndef TARGETING_LEOPARD
-    return CGColorSpaceCreateWithICCProfile(data.get());
-#else
-    RetainPtr<CGDataProviderRef> profileDataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
-    CGFloat ranges[] = {0.0, 255.0, 0.0, 255.0, 0.0, 255.0};
-    return CGColorSpaceCreateICCBased(3, ranges, profileDataProvider.get(), deviceRGBColorSpaceRef());
-#endif
-}
-#endif
-
 void ImageFrame::setColorProfile(const ColorProfile& colorProfile)
 {
-#if PLATFORM(CHROMIUM) && OS(DARWIN)
-    m_colorProfile = colorProfile;
-#else
-    notImplemented();
-#endif
+    // FIXME: Do we need this ImageFrame function anymore, on any port?
+    UNUSED_PARAM(colorProfile);
 }
 
 void ImageFrame::setStatus(FrameStatus status)
 {
     m_status = status;
-    if (m_status == FrameComplete) {
+    if (m_status == FrameComplete)
         m_bitmap.setDataComplete();  // Tell the bitmap it's done.
-#if PLATFORM(CHROMIUM) && OS(DARWIN)
-        // resolveColorSpace() and callees assume that the alpha channel is
-        // premultiplied, so don't apply the color profile if it isn't.
-        if (m_colorProfile.isEmpty() || (!m_premultiplyAlpha && hasAlpha()))
-            return;
-        RetainPtr<CGColorSpaceRef> cgColorSpace(AdoptCF, createColorSpace(m_colorProfile));
-        resolveColorSpace(m_bitmap.bitmap(), cgColorSpace.get());
-#endif
-    }
 }
 
 int ImageFrame::width() const