2011-02-02 Matthew Vosburgh <maf@chromium.org>
authorkbr@google.com <kbr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Feb 2011 20:25:58 +0000 (20:25 +0000)
committerkbr@google.com <kbr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Feb 2011 20:25:58 +0000 (20:25 +0000)
        Reviewed by Kenneth Russell.

        Some favicons not correctly decoded by Chromium/Mac
        https://bugs.webkit.org/show_bug.cgi?id=53448

        * src/WebImageCG.cpp:
        (WebKit::WebImage::fromData):

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

Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebImageCG.cpp

index 04294db..0457659 100644 (file)
@@ -1,3 +1,13 @@
+2011-02-02  Matthew Vosburgh  <maf@chromium.org>
+
+        Reviewed by Kenneth Russell.
+
+        Some favicons not correctly decoded by Chromium/Mac
+        https://bugs.webkit.org/show_bug.cgi?id=53448
+
+        * src/WebImageCG.cpp:
+        (WebKit::WebImage::fromData):
+
 2011-02-02  Dimitri Glazkov  <dglazkov@chromium.org>
 
         Reviewed by Dave Hyatt.
index 045c8be..dda829f 100644 (file)
@@ -49,20 +49,38 @@ namespace WebKit {
 
 WebImage WebImage::fromData(const WebData& data, const WebSize& desiredSize)
 {
-    // FIXME: Do something like what WebImageSkia.cpp does to enumerate frames.
-    // Not sure whether the CG decoder uses the same frame ordering rules (if so
-    // we can just use the same logic).
-
     ImageSource source;
     source.setData(PassRefPtr<SharedBuffer>(data).get(), true);
     if (!source.isSizeAvailable())
         return WebImage();
 
-    RetainPtr<CGImageRef> frame0(AdoptCF, source.createFrameAtIndex(0));
-    if (!frame0)
+    // 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();
+    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);
+        if (WebSize(frameSize) == desiredSize) {
+            index = i;
+            break; // Perfect match.
+        }
+        const int frameArea = frameSize.width() * frameSize.height();
+        if (frameArea < (desiredSize.width * desiredSize.height))
+            break; // No more frames that are large enough.
+
+        if (!i || (frameArea < frameAreaAtIndex)) {
+            index = i; // Closer to desired area than previous best match.
+            frameAreaAtIndex = frameArea;
+        }
+    }
+
+    RetainPtr<CGImageRef> frame(AdoptCF, source.createFrameAtIndex(index));
+    if (!frame)
         return WebImage();
 
-    return WebImage(frame0.get());
+    return WebImage(frame.get());
 }
 
 void WebImage::reset()