pull from android: use registry to build up list of image codecs



git-svn-id: http://skia.googlecode.com/svn/trunk@76 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/images/SkImageDecoder_libbmp.cpp b/src/images/SkImageDecoder_libbmp.cpp
index 32a7a6d..a4dcbf6 100644
--- a/src/images/SkImageDecoder_libbmp.cpp
+++ b/src/images/SkImageDecoder_libbmp.cpp
@@ -20,6 +20,7 @@
 #include "SkStream.h"
 #include "SkColorPriv.h"
 #include "SkTDArray.h"
+#include "SkTRegistry.h"
 
 class SkBMPImageDecoder : public SkImageDecoder {
 public:
@@ -34,8 +35,7 @@
                           SkBitmap::Config pref, Mode mode);
 };
 
-SkImageDecoder* SkImageDecoder_BMP_Factory(SkStream*);
-SkImageDecoder* SkImageDecoder_BMP_Factory(SkStream* stream) {
+static SkImageDecoder* Factory(SkStream* stream) {
     static const char kBmpMagic[] = { 'B', 'M' };
     
     size_t len = stream->getLength();
@@ -49,6 +49,8 @@
     return NULL;
 }
 
+static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory);
+
 ///////////////////////////////////////////////////////////////////////////////
 
 class SkBmpDecoderCallback : public image_codec::BmpDecoderCallback {
diff --git a/src/images/SkImageDecoder_libgif.cpp b/src/images/SkImageDecoder_libgif.cpp
index 519366a..ed8817a 100644
--- a/src/images/SkImageDecoder_libgif.cpp
+++ b/src/images/SkImageDecoder_libgif.cpp
@@ -326,7 +326,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkImageDecoder* SkImageDecoder_GIF_Factory(SkStream* stream) {
+#include "SkTRegistry.h"
+
+static SkImageDecoder* Factory(SkStream* stream) {
     char buf[GIF_STAMP_LEN];
     if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
         if (memcmp(GIF_STAMP,   buf, GIF_STAMP_LEN) == 0 ||
@@ -338,3 +340,4 @@
     return NULL;
 }
 
+static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory);
diff --git a/src/images/SkImageDecoder_libico.cpp b/src/images/SkImageDecoder_libico.cpp
index b179a6b..9f21e13 100644
--- a/src/images/SkImageDecoder_libico.cpp
+++ b/src/images/SkImageDecoder_libico.cpp
@@ -44,23 +44,6 @@
 
 /////////////////////////////////////////////////////////////////////////////////////////
 
-SkImageDecoder* SkImageDecoder_ICO_Factory(SkStream*);
-SkImageDecoder* SkImageDecoder_ICO_Factory(SkStream* stream)
-{
-    //i'm going to check if we basically have 0,0,1,0 (reserved = 0, type = 1)
-    //is that required and sufficient?
-    SkAutoMalloc autoMal(4);
-    unsigned char* buf = (unsigned char*)autoMal.get();
-    stream->read((void*)buf, 4);
-    int reserved = read2Bytes(buf, 0);
-    int type = read2Bytes(buf, 2);
-    if (reserved != 0 || type != 1) //it's not an ico
-        return NULL;
-    return SkNEW(SkICOImageDecoder);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
 SkICOImageDecoder::SkICOImageDecoder()
 {
 }
@@ -386,3 +369,24 @@
     *address = SkPackARGB32(alpha, red & alpha, green & alpha, blue & alpha);
 }
 
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkTRegistry.h"
+
+static SkImageDecoder* Factory(SkStream* stream) {
+    // Check to see if the first four bytes are 0,0,1,0
+    // FIXME: Is that required and sufficient?
+    SkAutoMalloc autoMal(4);
+    unsigned char* buf = (unsigned char*)autoMal.get();
+    stream->read((void*)buf, 4);
+    int reserved = read2Bytes(buf, 0);
+    int type = read2Bytes(buf, 2);
+    if (reserved != 0 || type != 1) {
+        // This stream does not represent an ICO image.
+        return NULL;
+    }
+    return SkNEW(SkICOImageDecoder);
+}
+
+static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory);
+
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index 5133997..018c96c 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -51,24 +51,6 @@
                           SkBitmap::Config pref, Mode);
 };
 
-SkImageDecoder* SkImageDecoder_JPEG_Factory(SkStream* stream) {
-    static const char gHeader[] = { 0xFF, 0xD8, 0xFF };
-    static const size_t HEADER_SIZE = sizeof(gHeader);
-
-    char buffer[HEADER_SIZE];
-    size_t len = stream->read(buffer, HEADER_SIZE);
-
-    if (len != HEADER_SIZE) {
-        return NULL;   // can't read enough
-    }
-    
-    if (memcmp(buffer, gHeader, HEADER_SIZE)) {
-        return NULL;
-    }
-
-    return SkNEW(SkJPEGImageDecoder);
-}
-
 //////////////////////////////////////////////////////////////////////////
 
 #include "SkTime.h"
@@ -789,20 +771,30 @@
     }
 };
 
-SkImageEncoder* SkImageEncoder_JPEG_Factory();
-SkImageEncoder* SkImageEncoder_JPEG_Factory() {
-    return SkNEW(SkJPEGImageEncoder);
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkTRegistry.h"
+
+static SkImageDecoder* DFactory(SkStream* stream) {
+    static const char gHeader[] = { 0xFF, 0xD8, 0xFF };
+    static const size_t HEADER_SIZE = sizeof(gHeader);
+
+    char buffer[HEADER_SIZE];
+    size_t len = stream->read(buffer, HEADER_SIZE);
+
+    if (len != HEADER_SIZE) {
+        return NULL;   // can't read enough
+    }
+    if (memcmp(buffer, gHeader, HEADER_SIZE)) {
+        return NULL;
+    }
+    return SkNEW(SkJPEGImageDecoder);
 }
 
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG
-
-void SkImageDecoder::UnitTest() {
-    SkBitmap    bm;
-
-    (void)SkImageDecoder::DecodeFile("logo.jpg", &bm);
+static SkImageEncoder* EFactory(SkImageEncoder::Type t) {
+    return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL;
 }
 
-#endif
+static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(DFactory);
+static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(EFactory);
+
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
index fedb8df..b616eee 100644
--- a/src/images/SkImageDecoder_libpng.cpp
+++ b/src/images/SkImageDecoder_libpng.cpp
@@ -58,15 +58,6 @@
     png_infop info_ptr;
 };
 
-SkImageDecoder* SkImageDecoder_PNG_Factory(SkStream* stream) {
-    char buf[PNG_BYTES_TO_CHECK];
-    if (stream->read(buf, PNG_BYTES_TO_CHECK) == PNG_BYTES_TO_CHECK &&
-            !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) {
-        return SkNEW(SkPNGImageDecoder);
-    }
-    return NULL;
-}
-
 static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) {
     SkStream* sk_stream = (SkStream*) png_ptr->io_ptr;
     size_t bytes = sk_stream->read(data, length);
@@ -787,8 +778,22 @@
     return true;
 }
 
-SkImageEncoder* SkImageEncoder_PNG_Factory();
-SkImageEncoder* SkImageEncoder_PNG_Factory() {
-    return SkNEW(SkPNGImageEncoder);
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkTRegistry.h"
+
+static SkImageDecoder* DFactory(SkStream* stream) {
+    char buf[PNG_BYTES_TO_CHECK];
+    if (stream->read(buf, PNG_BYTES_TO_CHECK) == PNG_BYTES_TO_CHECK &&
+        !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) {
+        return SkNEW(SkPNGImageDecoder);
+    }
+    return NULL;
 }
 
+static SkImageEncoder* EFactory(SkImageEncoder::Type t) {
+    return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL;
+}
+
+static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(EFactory);
+static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(DFactory);
diff --git a/src/images/SkImageDecoder_wbmp.cpp b/src/images/SkImageDecoder_wbmp.cpp
index 9d188f6..ac242ea 100644
--- a/src/images/SkImageDecoder_wbmp.cpp
+++ b/src/images/SkImageDecoder_wbmp.cpp
@@ -77,16 +77,6 @@
     }
 };
     
-SkImageDecoder* SkImageDecoder_WBMP_Factory(SkStream* stream)
-{
-    wbmp_head   head;
-
-    if (head.init(stream)) {
-        return SkNEW(SkWBMPImageDecoder);
-    }
-    return NULL;
-}
-
 static void expand_bits_to_bytes(uint8_t dst[], const uint8_t src[], int bits)
 {
     int bytes = bits >> 3;
@@ -165,3 +155,18 @@
     return true;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkTRegistry.h"
+
+static SkImageDecoder* Factory(SkStream* stream) {
+    wbmp_head   head;
+
+    if (head.init(stream)) {
+        return SkNEW(SkWBMPImageDecoder);
+    }
+    return NULL;
+}
+
+static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory);
+