Honor pref config in image decoding whenever possible.
authorweita@google.com <weita@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 11 May 2009 16:06:22 +0000 (16:06 +0000)
committerweita@google.com <weita@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 11 May 2009 16:06:22 +0000 (16:06 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@173 2bbb7eff-a529-9590-31e7-b0007b416f81

include/images/SkImageDecoder.h
src/images/SkImageDecoder.cpp

index c85a7cd..d2b23a1 100644 (file)
@@ -29,7 +29,7 @@ class SkStream;
 class SkImageDecoder {
 public:
     virtual ~SkImageDecoder();
-    
+
     enum Format {
         kUnknown_Format,
         kBMP_Format,
@@ -38,10 +38,10 @@ public:
         kJPEG_Format,
         kPNG_Format,
         kWBMP_Format,
-        
+
         kLastKnownFormat = kWBMP_Format
     };
-        
+
     /** Return the compressed data's format (see Format enum)
     */
     virtual Format getFormat() const;
@@ -50,14 +50,14 @@ public:
         The default setting is true.
     */
     bool getDitherImage() const { return fDitherImage; }
-    
+
     /** Set to true if the the decoder should try to dither the resulting image.
         The default setting is true.
     */
     void setDitherImage(bool dither) { fDitherImage = dither; }
 
     /** \class Peeker
-    
+
         Base class for optional callbacks to retrieve meta/chunk data out of
         an image as it is being decoded.
     */
@@ -71,9 +71,9 @@ public:
 
     Peeker* getPeeker() const { return fPeeker; }
     Peeker* setPeeker(Peeker*);
-    
+
     /** \class Peeker
-    
+
         Base class for optional callbacks to retrieve meta/chunk data out of
         an image as it is being decoded.
     */
@@ -100,7 +100,7 @@ public:
     // approximate the sample size.
     int getSampleSize() const { return fSampleSize; }
     void setSampleSize(int size);
-    
+
     /** Reset the sampleSize to its default of 1
      */
     void resetSampleSize() { this->setSampleSize(1); }
@@ -113,7 +113,7 @@ public:
         it is possible that cancelDecode() will be called, but will be ignored
         and decode() will return true (assuming no other problems were
         encountered).
-     
+
         This state is automatically reset at the beginning of decode().
      */
     void cancelDecode() {
@@ -130,16 +130,19 @@ public:
         kDecodeBounds_Mode, //!< only return width/height/config in bitmap
         kDecodePixels_Mode  //!< return entire bitmap (including pixels)
     };
-    
+
     /** Given a stream, decode it into the specified bitmap.
         If the decoder can decompress the image, it calls bitmap.setConfig(),
         and then if the Mode is kDecodePixels_Mode, call allocPixelRef(),
         which will allocated a pixelRef. To access the pixel memory, the codec
         needs to call lockPixels/unlockPixels on the
         bitmap. It can then set the pixels with the decompressed image.
-        If the image cannot be decompressed, return false.
-        
-        note: document use of Allocator, Peeker and Chooser 
+    *   If the image cannot be decompressed, return false. After the
+    *   decoding, the function converts the decoded config in bitmap
+    *   to pref if possible. Whether a conversion is feasible is
+    *   tested by Bitmap::canCopyTo(pref).
+
+        note: document use of Allocator, Peeker and Chooser
     */
     bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode);
 
@@ -198,7 +201,7 @@ public:
         return DecodeStream(stream, bitmap, SkBitmap::kNo_Config,
                             kDecodePixels_Mode);
     }
-    
+
     /** Return the default config for the running device.
         Currently this used as a suggestion to image decoders that need to guess
         what config they should decode into.
@@ -227,14 +230,14 @@ protected:
         true, your onDecode() should stop and return false.
         Each subclass needs to decide how often it can query this, to balance
         responsiveness with performance.
-     
+
         Calling this outside of onDecode() may return undefined values.
      */
 
 public:
     bool shouldCancelDecode() const { return fShouldCancelDecode; }
 
-protected:    
+protected:
     SkImageDecoder();
 
     // helper function for decoders to handle the (common) case where there is only
index f0fff1b..b910df6 100644 (file)
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -90,37 +90,6 @@ bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-
-/*  Technically, this should be 342, since that is the cutoff point between
-    an index and 32bit bitmap (they take equal ram), but since 32bit is almost
-    always faster, I bump up the value a bit.
-*/
-#define MIN_SIZE_FOR_INDEX  (512)
-
-/*  Return the "optimal" config for this bitmap. In this case, we just look to
-    promote index bitmaps to full-color, since those are a little faster to
-    draw (fewer memory lookups).
-
-    Seems like we could expose this to the caller through some exising or new
-    proxy object, allowing them to decide (after sniffing some aspect of the
-    original bitmap) what config they really want.
- */
-static SkBitmap::Config optimal_config(const SkBitmap& bm,
-                                       SkBitmap::Config pref) {
-    if (bm.config() != pref) {
-        if (bm.config() == SkBitmap::kIndex8_Config) {
-            Sk64 size64 = bm.getSize64();
-            if (size64.is32()) {
-                int32_t size = size64.get32();
-                if (size < MIN_SIZE_FOR_INDEX) {
-                    return SkBitmap::kARGB_8888_Config;
-                }
-            }
-        }
-    }
-    return bm.config();
-}
-
 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
                             SkBitmap::Config pref, Mode mode) {
     // pass a temporary bitmap, so that if we return false, we are assured of
@@ -134,13 +103,12 @@ bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
         return false;
     }
 
-    SkBitmap::Config c = optimal_config(tmp, pref);
-    if (c != tmp.config()) {
+    if (tmp.config() != pref && tmp.canCopyTo(pref)) {
         if (mode == kDecodeBounds_Mode) {
-            tmp.setConfig(c, tmp.width(), tmp.height());
-        } else {
+            tmp.setConfig(pref, tmp.width(), tmp.height());
+        } else if (mode == kDecodePixels_Mode) {
             SkBitmap tmp2;
-            if (tmp.copyTo(&tmp2, c, this->getAllocator())) {
+            if (tmp.copyTo(&tmp2, pref, this->getAllocator())) {
                 tmp.swap(tmp2);
             }
         }