[chromium] WebImage should use ImageDecoder directly
authorhclam@chromium.org <hclam@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Sep 2012 22:29:54 +0000 (22:29 +0000)
committerhclam@chromium.org <hclam@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Sep 2012 22:29:54 +0000 (22:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=96135

Reviewed by Adam Barth.

This patch is for preparation of deferred image decoding.
ImageSource will be used as a portal to access deferred image decoder
by BitmapImage, it should not be accessible through WebKit APIs.

WebImage now calls ImageDecoder directly which is the actual
implementation of an image decoder.

Tests: WebImageTest.PNGImage
       WebImageTest.ICOImage

* WebKit.gypi:
* src/WebImageSkia.cpp:
(WebKit::WebImage::fromData):
(WebKit::WebImage::framesFromData):
* tests/WebImageTest.cpp: Added.
(WebKit):
(WebKit::readFile):
(WebKit::TEST):
* tests/data/black-and-white.ico: Added.
* tests/data/white-1x1.png: Added.

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

Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/WebKit.gypi
Source/WebKit/chromium/src/WebImageSkia.cpp
Source/WebKit/chromium/tests/WebImageTest.cpp [new file with mode: 0644]
Source/WebKit/chromium/tests/data/black-and-white.ico [new file with mode: 0644]
Source/WebKit/chromium/tests/data/white-1x1.png [new file with mode: 0644]

index d73a4a5..b7f2c42 100644 (file)
@@ -1,3 +1,31 @@
+2012-09-18  Alpha Lam  <hclam@chromium.org>
+
+        [chromium] WebImage should use ImageDecoder directly
+        https://bugs.webkit.org/show_bug.cgi?id=96135
+
+        Reviewed by Adam Barth.
+
+        This patch is for preparation of deferred image decoding.
+        ImageSource will be used as a portal to access deferred image decoder
+        by BitmapImage, it should not be accessible through WebKit APIs.
+
+        WebImage now calls ImageDecoder directly which is the actual
+        implementation of an image decoder.
+
+        Tests: WebImageTest.PNGImage
+               WebImageTest.ICOImage
+
+        * WebKit.gypi:
+        * src/WebImageSkia.cpp:
+        (WebKit::WebImage::fromData):
+        (WebKit::WebImage::framesFromData):
+        * tests/WebImageTest.cpp: Added.
+        (WebKit):
+        (WebKit::readFile):
+        (WebKit::TEST):
+        * tests/data/black-and-white.ico: Added.
+        * tests/data/white-1x1.png: Added.
+
 2012-09-18  Tommy Widenflycht  <tommyw@google.com>
 
         MediaStream API: Create a flag to enable PeerConnection00
index edebf1b..b16a601 100644 (file)
             'tests/WebCompositorInputHandlerImplTest.cpp',
             'tests/WebFrameTest.cpp',
             'tests/WebInputEventConversionTest.cpp',
+            'tests/WebImageTest.cpp',
             'tests/WebMediaPlayerClientImplTest.cpp',
             'tests/WebPageNewSerializerTest.cpp',
             'tests/WebPageSerializerTest.cpp',
index e1a9260..a758cfc 100644 (file)
@@ -31,7 +31,7 @@
 #include "config.h"
 
 #include "Image.h"
-#include "ImageSource.h"
+#include "ImageDecoder.h"
 #include "NativeImageSkia.h"
 #include "SharedBuffer.h"
 
@@ -51,19 +51,20 @@ namespace WebKit {
 
 WebImage WebImage::fromData(const WebData& data, const WebSize& desiredSize)
 {
-    ImageSource source;
-    source.setData(PassRefPtr<SharedBuffer>(data).get(), true);
-    if (!source.isSizeAvailable())
+    RefPtr<SharedBuffer> buffer = PassRefPtr<SharedBuffer>(data);
+    OwnPtr<ImageDecoder> decoder(adoptPtr(ImageDecoder::create(*buffer.get(), ImageSource::AlphaPremultiplied, ImageSource::GammaAndColorProfileApplied)));
+    decoder->setData(buffer.get(), true);
+    if (!decoder->isSizeAvailable())
         return WebImage();
 
     // Frames are arranged by decreasing size, then decreasing bit depth.
     // Pick the frame closest to |desiredSize|'s area without being smaller,
     // which has the highest bit depth.
-    const size_t frameCount = source.frameCount();
+    const size_t frameCount = decoder->frameCount();
     size_t index = 0;  // Default to first frame if none are large enough.
     int frameAreaAtIndex = 0;
     for (size_t i = 0; i < frameCount; ++i) {
-        const IntSize frameSize = source.frameSizeAtIndex(i);
+        const IntSize frameSize = decoder->frameSizeAtIndex(i);
         if (WebSize(frameSize) == desiredSize) {
             index = i;
             break;  // Perfect match.
@@ -79,11 +80,15 @@ WebImage WebImage::fromData(const WebData& data, const WebSize& desiredSize)
         }
     }
 
-    OwnPtr<NativeImageSkia> frame = adoptPtr(source.createFrameAtIndex(index));
+    ImageFrame* frame = decoder->frameBufferAtIndex(index);
     if (!frame)
         return WebImage();
 
-    return WebImage(frame->bitmap());
+    OwnPtr<NativeImageSkia> image = adoptPtr(frame->asNewNativeImage());
+    if (!image)
+        return WebImage();
+
+    return WebImage(image->bitmap());
 }
 
 WebVector<WebImage> WebImage::framesFromData(const WebData& data)
@@ -91,26 +96,31 @@ WebVector<WebImage> WebImage::framesFromData(const WebData& data)
     // This is to protect from malicious images. It should be big enough that it's never hit in pracice.
     const size_t maxFrameCount = 8;
 
-    ImageSource source;
-    source.setData(PassRefPtr<SharedBuffer>(data).get(), true);
-    if (!source.isSizeAvailable())
+    RefPtr<SharedBuffer> buffer = PassRefPtr<SharedBuffer>(data);
+    OwnPtr<ImageDecoder> decoder(adoptPtr(ImageDecoder::create(*buffer.get(), ImageSource::AlphaPremultiplied, ImageSource::GammaAndColorProfileApplied)));
+    decoder->setData(buffer.get(), true);
+    if (!decoder->isSizeAvailable())
         return WebVector<WebImage>();
 
     // Frames are arranged by decreasing size, then decreasing bit depth.
     // Keep the first frame at every size, has the highest bit depth.
-    const size_t frameCount = source.frameCount();
+    const size_t frameCount = decoder->frameCount();
     IntSize lastSize;
 
     Vector<WebImage> frames;
     for (size_t i = 0; i < std::min(frameCount, maxFrameCount); ++i) {
-        const IntSize frameSize = source.frameSizeAtIndex(i);
+        const IntSize frameSize = decoder->frameSizeAtIndex(i);
         if (frameSize == lastSize)
             continue;
         lastSize = frameSize;
 
-        OwnPtr<NativeImageSkia> frame = adoptPtr(source.createFrameAtIndex(i));
-        if (frame)
-            frames.append(WebImage(frame->bitmap()));
+        ImageFrame* frame = decoder->frameBufferAtIndex(i);
+        if (!frame)
+            continue;
+
+        OwnPtr<NativeImageSkia> image = adoptPtr(frame->asNewNativeImage());
+        if (image.get())
+            frames.append(WebImage(image->bitmap()));
     }
 
     return frames;
diff --git a/Source/WebKit/chromium/tests/WebImageTest.cpp b/Source/WebKit/chromium/tests/WebImageTest.cpp
new file mode 100644 (file)
index 0000000..1ecf00f
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <public/WebImage.h>
+
+#include "FileSystem.h"
+#include "SharedBuffer.h"
+#include <gtest/gtest.h>
+#include <public/WebData.h>
+#include <public/WebSize.h>
+#include <webkit/support/webkit_support.h>
+
+using namespace WebCore;
+using namespace WebKit;
+
+namespace {
+
+static PassRefPtr<SharedBuffer> readFile(const char* fileName)
+{
+    String filePath = webkit_support::GetWebKitRootDir();
+    filePath.append("/Source/WebKit/chromium/tests/data/");
+    filePath.append(fileName);
+
+    long long fileSize;
+    if (!getFileSize(filePath, fileSize))
+        return 0;
+
+    PlatformFileHandle handle = openFile(filePath, OpenForRead);
+    int fileLength = static_cast<int>(fileSize);
+    Vector<char> buffer(fileLength);
+    readFromFile(handle, buffer.data(), fileLength);
+    closeFile(handle);
+    return SharedBuffer::adoptVector(buffer);
+}
+
+TEST(WebImageTest, PNGImage)
+{
+    RefPtr<SharedBuffer> data = readFile("white-1x1.png");
+    ASSERT_TRUE(data.get());
+
+    WebImage image = WebImage::fromData(WebData(data), WebSize());
+    EXPECT_TRUE(image.size() == WebSize(1, 1));
+    SkAutoLockPixels autoLock(image.getSkBitmap());
+    EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), image.getSkBitmap().getColor(0, 0));
+}
+
+TEST(WebImageTest, ICOImage)
+{
+    RefPtr<SharedBuffer> data = readFile("black-and-white.ico");
+    ASSERT_TRUE(data.get());
+
+    WebVector<WebImage> images = WebImage::framesFromData(WebData(data));
+    ASSERT_EQ(2u, images.size());
+    EXPECT_TRUE(images[0].size() == WebSize(2, 2));
+    EXPECT_TRUE(images[1].size() == WebSize(1, 1));
+    SkAutoLockPixels autoLock1(images[0].getSkBitmap());
+    EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), images[0].getSkBitmap().getColor(0, 0));
+    SkAutoLockPixels autoLock2(images[1].getSkBitmap());
+    EXPECT_EQ(SkColorSetARGB(255, 0, 0, 0), images[1].getSkBitmap().getColor(0, 0));
+}
+
+} // namespace
diff --git a/Source/WebKit/chromium/tests/data/black-and-white.ico b/Source/WebKit/chromium/tests/data/black-and-white.ico
new file mode 100644 (file)
index 0000000..6bdf9ca
Binary files /dev/null and b/Source/WebKit/chromium/tests/data/black-and-white.ico differ
diff --git a/Source/WebKit/chromium/tests/data/white-1x1.png b/Source/WebKit/chromium/tests/data/white-1x1.png
new file mode 100644 (file)
index 0000000..ccf7a6c
Binary files /dev/null and b/Source/WebKit/chromium/tests/data/white-1x1.png differ