Updates to images project.
authorscroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 17 Apr 2013 21:07:55 +0000 (21:07 +0000)
committerscroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 17 Apr 2013 21:07:55 +0000 (21:07 +0000)
Use the SkImageEncoder_Factory on all platforms. On Windows and Mac,
register the platform's image encoder as an option for
SkImageEncoder::Create. Also add more types that can be decoded.

Update comments for SkImageDecoder to be more accurate.

Add more types to SkImageEncoder::Type, and return the correct type of
encoder, if it exists.

Use a custom version of SkImageDecoder::Factory on Windows and Mac to
check the stream for registered decoders before defaulting to the platform's
version. Share code with the existing SkImageDecoder::Factory method.

Preparation for testing decoders and encoders:
BUG=https://code.google.com/p/skia/issues/detail?id=1241

Review URL: https://codereview.chromium.org/14298010

git-svn-id: http://skia.googlecode.com/svn/trunk@8730 2bbb7eff-a529-9590-31e7-b0007b416f81

gyp/images.gyp
include/images/SkImageDecoder.h
include/images/SkImageEncoder.h
src/images/SkImageDecoder_FactoryDefault.cpp [new file with mode: 0644]
src/images/SkImageDecoder_FactoryRegistrar.cpp [moved from src/images/SkImageDecoder_Factory.cpp with 61% similarity]
src/ports/SkImageDecoder_CG.cpp
src/ports/SkImageDecoder_WIC.cpp

index 40d6426..85b689d 100644 (file)
@@ -1,4 +1,4 @@
-{
+{
   'targets': [
     {
       'target_name': 'images',
@@ -36,7 +36,8 @@
         '../src/images/SkBitmapRegionDecoder.cpp',
 
         '../src/images/SkImageDecoder.cpp',
-        '../src/images/SkImageDecoder_Factory.cpp',
+        '../src/images/SkImageDecoder_FactoryDefault.cpp',
+        '../src/images/SkImageDecoder_FactoryRegistrar.cpp',
         '../src/images/SkImageDecoder_libbmp.cpp',
         '../src/images/SkImageDecoder_libgif.cpp',
         '../src/images/SkImageDecoder_libico.cpp',
         [ 'skia_os == "win"', {
           'sources!': [
             '../src/images/SkFDStream.cpp',
-            '../src/images/SkImageDecoder_Factory.cpp',
+            '../src/images/SkImageDecoder_FactoryDefault.cpp',
             '../src/images/SkImageDecoder_libgif.cpp',
             '../src/images/SkImageDecoder_libpng.cpp',
-            '../src/images/SkImageEncoder_Factory.cpp',
             '../src/images/SkMovie_gif.cpp',
           ],
           'link_settings': {
         }],
         [ 'skia_os in ["mac", "ios"]', {
           'sources!': [
-            '../src/images/SkImageDecoder_Factory.cpp',
+            '../src/images/SkImageDecoder_FactoryDefault.cpp',
             '../src/images/SkImageDecoder_libpng.cpp',
             '../src/images/SkImageDecoder_libgif.cpp',
-            '../src/images/SkImageEncoder_Factory.cpp',
             '../src/images/SkMovie_gif.cpp',
           ],
         },{ #else if skia_os != mac
index 33802ed..38e77f4 100644 (file)
@@ -26,7 +26,7 @@ class SkImageDecoder {
 public:
     virtual ~SkImageDecoder();
 
-    // Should be consistent with kFormatName
+    // Should be consistent with sFormatName
     enum Format {
         kUnknown_Format,
         kBMP_Format,
@@ -40,11 +40,12 @@ public:
         kLastKnownFormat = kWEBP_Format
     };
 
-    /** Return the compressed data's format (see Format enum)
+    /** Return the format of image this decoder can decode. If this decoder can decode multiple
+        formats, kUnknown_Format will be returned.
     */
     virtual Format getFormat() const;
 
-    /** Return the compressed data's format name.
+    /** Return a readable string of the value returned by getFormat().
     */
     const char* getFormatName() const;
 
index d4d7169..5db32c3 100644 (file)
@@ -16,9 +16,13 @@ class SkWStream;
 class SkImageEncoder {
 public:
     enum Type {
+        kBMP_Type,
+        kGIF_Type,
+        kICO_Type,
         kJPEG_Type,
         kPNG_Type,
-        kWEBP_Type
+        kWBMP_Type,
+        kWEBP_Type,
     };
     static SkImageEncoder* Create(Type);
 
diff --git a/src/images/SkImageDecoder_FactoryDefault.cpp b/src/images/SkImageDecoder_FactoryDefault.cpp
new file mode 100644 (file)
index 0000000..565519a
--- /dev/null
@@ -0,0 +1,37 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkImageDecoder.h"
+#include "SkMovie.h"
+#include "SkStream.h"
+#include "SkTRegistry.h"
+
+extern SkImageDecoder* image_decoder_from_stream(SkStream*);
+
+SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
+    return image_decoder_from_stream(stream);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+typedef SkTRegistry<SkMovie*, SkStream*> MovieReg;
+
+SkMovie* SkMovie::DecodeStream(SkStream* stream) {
+    const MovieReg* curr = MovieReg::Head();
+    while (curr) {
+        SkMovie* movie = curr->factory()(stream);
+        if (movie) {
+            return movie;
+        }
+        // we must rewind only if we got NULL, since we gave the stream to the
+        // movie, who may have already started reading from it
+        stream->rewind();
+        curr = curr->next();
+    }
+    return NULL;
+}
similarity index 61%
rename from src/images/SkImageDecoder_Factory.cpp
rename to src/images/SkImageDecoder_FactoryRegistrar.cpp
index c276a3d..6cc417a 100644 (file)
@@ -1,24 +1,27 @@
-
 /*
- * Copyright 2006 The Android Open Source Project
+ * Copyright 2013 The Android Open Source Project
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
-
 #include "SkImageDecoder.h"
-#include "SkMovie.h"
 #include "SkStream.h"
 #include "SkTRegistry.h"
 
+// This file is used for registration of SkImageDecoders. It also holds a function
+// for checking all the the registered SkImageDecoders for one that matches an
+// input SkStream.
+
 typedef SkTRegistry<SkImageDecoder*, SkStream*> DecodeReg;
 
 // N.B. You can't use "DecodeReg::gHead here" due to complex C++
 // corner cases.
 template DecodeReg* SkTRegistry<SkImageDecoder*, SkStream*>::gHead;
 
-SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
+SkImageDecoder* image_decoder_from_stream(SkStream*);
+
+SkImageDecoder* image_decoder_from_stream(SkStream* stream) {
     SkImageDecoder* codec = NULL;
     const DecodeReg* curr = DecodeReg::Head();
     while (curr) {
@@ -42,22 +45,3 @@ SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
     }
     return NULL;
 }
-
-/////////////////////////////////////////////////////////////////////////
-
-typedef SkTRegistry<SkMovie*, SkStream*> MovieReg;
-
-SkMovie* SkMovie::DecodeStream(SkStream* stream) {
-    const MovieReg* curr = MovieReg::Head();
-    while (curr) {
-        SkMovie* movie = curr->factory()(stream);
-        if (movie) {
-            return movie;
-        }
-        // we must rewind only if we got NULL, since we gave the stream to the
-        // movie, who may have already started reading from it
-        stream->rewind();
-        curr = curr->next();
-    }
-    return NULL;
-}
index f8ec108..9fc49a4 100644 (file)
@@ -110,8 +110,16 @@ bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
 
 ///////////////////////////////////////////////////////////////////////////////
 
+extern SkImageDecoder* image_decoder_from_stream(SkStream*);
+
 SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
-    return SkNEW(SkImageDecoder_CG);
+    SkImageDecoder* decoder = image_decoder_from_stream(stream);
+    if (NULL == decoder) {
+        // If no image decoder specific to the stream exists, use SkImageDecoder_CG.
+        return SkNEW(SkImageDecoder_CG);
+    } else {
+        return decoder;
+    }
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -174,6 +182,15 @@ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm,
 
     CFStringRef type;
     switch (fType) {
+        case kICO_Type:
+            type = kUTTypeICO;
+            break;
+        case kBMP_Type:
+            type = kUTTypeBMP;
+            break;
+        case kGIF_Type:
+            type = kUTTypeGIF;
+            break;
         case kJPEG_Type:
             type = kUTTypeJPEG;
             break;
@@ -209,13 +226,22 @@ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm,
     return CGImageDestinationFinalize(dst);
 }
 
-SkImageEncoder* SkImageEncoder::Create(Type t) {
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkTRegistry.h"
+
+static SkImageEncoder* sk_imageencoder_cg_factory(SkImageEncoder::Type t) {
     switch (t) {
-        case kJPEG_Type:
-        case kPNG_Type:
+        case SkImageEncoder::kICO_Type:
+        case SkImageEncoder::kBMP_Type:
+        case SkImageEncoder::kGIF_Type:
+        case SkImageEncoder::kJPEG_Type:
+        case SkImageEncoder::kPNG_Type:
             break;
         default:
             return NULL;
     }
     return SkNEW_ARGS(SkImageEncoder_CG, (t));
 }
+
+static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_imageencoder_cg_factory);
index 4b869dd..17d75cc 100644 (file)
@@ -154,8 +154,16 @@ bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
 
 /////////////////////////////////////////////////////////////////////////
 
+extern SkImageDecoder* image_decoder_from_stream(SkStream*);
+
 SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
-    return SkNEW(SkImageDecoder_WIC);
+    SkImageDecoder* decoder = image_decoder_from_stream(stream);
+    if (NULL == decoder) {
+        // If no image decoder specific to the stream exists, use SkImageDecoder_WIC.
+        return SkNEW(SkImageDecoder_WIC);
+    } else {
+        return decoder;
+    }
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -183,6 +191,15 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream
 {
     GUID type;
     switch (fType) {
+        case kBMP_Type:
+            type = GUID_ContainerFormatBmp;
+            break;
+        case kGIF_Type:
+            type = GUID_ContainerFormatGif;
+            break;
+        case kICO_Type:
+            type = GUID_ContainerFormatIco;
+            break;
         case kJPEG_Type:
             type = GUID_ContainerFormatJpeg;
             break;
@@ -324,13 +341,22 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream
     return SUCCEEDED(hr);
 }
 
-SkImageEncoder* SkImageEncoder::Create(Type t) {
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkTRegistry.h"
+
+static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) {
     switch (t) {
-        case kJPEG_Type:
-        case kPNG_Type:
+        case SkImageEncoder::kBMP_Type:
+        case SkImageEncoder::kGIF_Type:
+        case SkImageEncoder::kICO_Type:
+        case SkImageEncoder::kJPEG_Type:
+        case SkImageEncoder::kPNG_Type:
             break;
         default:
             return NULL;
     }
     return SkNEW_ARGS(SkImageEncoder_WIC, (t));
 }
+
+static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_imageencoder_wic_factory);