[CG] ImageBuffer::ImageDataToDataURL: Remove alpha stuffing when encoding to JPEG
authornoel.gordon@gmail.com <noel.gordon@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 May 2012 18:34:16 +0000 (18:34 +0000)
committernoel.gordon@gmail.com <noel.gordon@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 May 2012 18:34:16 +0000 (18:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=85779

Reviewed by Eric Seidel.

No change in behavior. Covered by fast/canvas/webgl/premultiplyalpha-test.html

* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageDataToDataURL): Remove the need to stuff the alpha channel with 255.
Rename dataVector to premultipliedData and verify that its resize() worked. Rewrite
the premultiplication loop without the alpha channel = 255 part and ask the CG JPEG
encoder to ignore the alpha channel (kCGImageAlphaNoneSkipLast) instead.

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

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp

index 31f1aeb..9b73b32 100644 (file)
@@ -1,3 +1,18 @@
+2012-05-07  Noel Gordon  <noel.gordon@gmail.com>
+
+        [CG] ImageBuffer::ImageDataToDataURL: Remove alpha stuffing when encoding to JPEG
+        https://bugs.webkit.org/show_bug.cgi?id=85779
+
+        Reviewed by Eric Seidel.
+
+        No change in behavior. Covered by fast/canvas/webgl/premultiplyalpha-test.html
+
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::ImageDataToDataURL): Remove the need to stuff the alpha channel with 255.
+        Rename dataVector to premultipliedData and verify that its resize() worked. Rewrite
+        the premultiplication loop without the alpha channel = 255 part and ask the CG JPEG
+        encoder to ignore the alpha channel (kCGImageAlphaNoneSkipLast) instead.
+
 2012-05-07  Dominik Röttsches  <dominik.rottsches@linux.intel.com>
 
         [GTK] media/video-seek-past-end-playing.html times out
index 30ece1e..61d0422 100644 (file)
@@ -480,30 +480,32 @@ String ImageDataToDataURL(const ImageData& source, const String& mimeType, const
     RetainPtr<CFStringRef> uti = utiFromMIMEType(mimeType);
     ASSERT(uti);
 
+    CGImageAlphaInfo dataAlphaInfo = kCGImageAlphaLast;
     unsigned char* data = source.data()->data();
-    Vector<uint8_t> dataVector;
+    Vector<uint8_t> premultipliedData;
 
     if (CFEqual(uti.get(), jpegUTI())) {
         // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
-        dataVector.resize(4 * source.width() * source.height());
-        unsigned char *out = dataVector.data();
-        
-        for (int i = 0; i < source.width() * source.height(); i++) {
-            // Multiply color data by alpha, and set alpha to 255.
-            int alpha = data[4 * i + 3];
+        size_t size = 4 * source.width() * source.height();
+        if (!premultipliedData.tryReserveCapacity(size))
+            return "data:,";
+
+        unsigned char *buffer = premultipliedData.data();
+        for (size_t i = 0; i < size; i += 4) {
+            unsigned alpha = data[i + 3];
             if (alpha != 255) {
-                out[4 * i + 0] = data[4 * i + 0] * alpha / 255;
-                out[4 * i + 1] = data[4 * i + 1] * alpha / 255;
-                out[4 * i + 2] = data[4 * i + 2] * alpha / 255;
+                buffer[i + 0] = data[i + 0] * alpha / 255;
+                buffer[i + 1] = data[i + 1] * alpha / 255;
+                buffer[i + 2] = data[i + 2] * alpha / 255;
             } else {
-                out[4 * i + 0] = data[4 * i + 0];
-                out[4 * i + 1] = data[4 * i + 1];
-                out[4 * i + 2] = data[4 * i + 2];
+                buffer[i + 0] = data[i + 0];
+                buffer[i + 1] = data[i + 1];
+                buffer[i + 2] = data[i + 2];
             }
-            out[4 * i + 3] = 255;
         }
 
-        data = out;
+        dataAlphaInfo = kCGImageAlphaNoneSkipLast; // Ignore the alpha channel.
+        data = premultipliedData.data();
     }
 
     RetainPtr<CGDataProviderRef> dataProvider;
@@ -513,7 +515,7 @@ String ImageDataToDataURL(const ImageData& source, const String& mimeType, const
 
     RetainPtr<CGImageRef> image;
     image.adoptCF(CGImageCreate(source.width(), source.height(), 8, 32, 4 * source.width(),
-                                deviceRGBColorSpaceRef(), kCGBitmapByteOrderDefault | kCGImageAlphaLast,
+                                deviceRGBColorSpaceRef(), kCGBitmapByteOrderDefault | dataAlphaInfo,
                                 dataProvider.get(), 0, false, kCGRenderingIntentDefault));
 
     return CGImageToDataURL(image.get(), mimeType, quality);