Improved codec link-forcing system by adding Encoder/Decoder creation entry points

http://codereview.appspot.com/5881055/




git-svn-id: http://skia.googlecode.com/svn/trunk@3481 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/cmykjpeg.cpp b/gm/cmykjpeg.cpp
index 67d2a60..224aaec 100644
--- a/gm/cmykjpeg.cpp
+++ b/gm/cmykjpeg.cpp
@@ -61,6 +61,10 @@
     typedef GM INHERITED;
 };
 
+void forceLinking() {
+    SkImageDecoder *creator = CreateJPEGImageDecoder();
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
 static GM* MyFactory(void*) { return new CMYKJpegGM; }
diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h
index cbae8b1..d0c4d21 100644
--- a/include/images/SkImageDecoder.h
+++ b/include/images/SkImageDecoder.h
@@ -332,5 +332,25 @@
     }
 };
 
+// This macro declares a global (i.e., non-class owned) creation entry point
+// for each decoder (e.g., CreateJPEGImageDecoder)
+#define DECLARE_DECODER_CREATOR(codec)          \
+    SkImageDecoder *Create ## codec ();
+
+// This macro defines the global creation entry point for each decoder. Each
+// decoder implementation that registers with the decoder factory must call it.
+#define DEFINE_DECODER_CREATOR(codec)           \
+    SkImageDecoder *Create ## codec () {        \
+        return SkNEW( Sk ## codec );            \
+    }
+
+// All the decoders known by Skia. Note that, depending on the compiler settings,
+// not all of these will be available
+DECLARE_DECODER_CREATOR(BMPImageDecoder);
+DECLARE_DECODER_CREATOR(GIFImageDecoder);
+DECLARE_DECODER_CREATOR(ICOImageDecoder);
+DECLARE_DECODER_CREATOR(JPEGImageDecoder);
+DECLARE_DECODER_CREATOR(PNGImageDecoder);
+DECLARE_DECODER_CREATOR(WBMPImageDecoder);
 
 #endif
diff --git a/include/images/SkImageEncoder.h b/include/images/SkImageEncoder.h
index b2f8cb6..907e28b 100644
--- a/include/images/SkImageEncoder.h
+++ b/include/images/SkImageEncoder.h
@@ -40,4 +40,21 @@
     virtual bool onEncode(SkWStream*, const SkBitmap&, int quality) = 0;
 };
 
+// This macro declares a global (i.e., non-class owned) creation entry point
+// for each encoder (e.g., CreateJPEGImageEncoder)
+#define DECLARE_ENCODER_CREATOR(codec)          \
+    SkImageEncoder *Create ## codec ();
+
+// This macro defines the global creation entry point for each encoder. Each
+// encoder implementation that registers with the encoder factory must call it.
+#define DEFINE_ENCODER_CREATOR(codec)           \
+    SkImageEncoder *Create ## codec () {        \
+        return SkNEW( Sk ## codec );            \
+    }
+
+// All the encoders known by Skia. Note that, depending on the compiler settings,
+// not all of these will be available
+DECLARE_ENCODER_CREATOR(JPEGImageEncoder);
+DECLARE_ENCODER_CREATOR(PNGImageEncoder);
+
 #endif
diff --git a/src/images/SkImageDecoder_Factory.cpp b/src/images/SkImageDecoder_Factory.cpp
index 2825f0d..f3cb120 100644
--- a/src/images/SkImageDecoder_Factory.cpp
+++ b/src/images/SkImageDecoder_Factory.cpp
@@ -12,37 +12,6 @@
 #include "SkStream.h"
 #include "SkTRegistry.h"
 
-//extern SkImageDecoder* sk_libbmp_dfactory(SkStream*);
-//extern SkImageDecoder* sk_libgif_dfactory(SkStream*);
-//extern SkImageDecoder* sk_libico_dfactory(SkStream*);
-//extern SkImageDecoder* sk_libjpeg_dfactory(SkStream*);
-//extern SkImageDecoder* sk_libpng_dfactory(SkStream*);
-//extern SkImageDecoder* sk_wbmp_dfactory(SkStream*);
-
-// To get the various image decoding classes to register themselves
-// pre-main we need to ensure they are linked into the application.
-// Ultimately we need to move to using DLLs rather than tightly
-// coupling the factory with the file format classes.
-void ForceLinking()
-{
-    SkImageDecoder* codec = NULL;
-
-    // TODO: rather than force the linking here expose a
-    // "Sk*ImageDecoderCreate" function for each codec
-    // and let the app add these calls to force the linking.
-    // Besides decoupling the codecs from the factory this
-    // will also give the app the ability to circumvent the
-    // factory and explicitly create a decoder w/o reaching
-    // into Skia's guts
-
-//    codec = sk_libbmp_dfactory(NULL);
-//    codec = sk_libgif_dfactory(NULL);
-//    codec = sk_libico_dfactory(NULL);
-//    codec = sk_libjpeg_dfactory(NULL);
-//    codec = sk_libpng_dfactory(NULL);
-//    codec = sk_wbmp_dfactory(NULL);
-}
-
 typedef SkTRegistry<SkImageDecoder*, SkStream*> DecodeReg;
 
 // N.B. You can't use "DecodeReg::gHead here" due to complex C++
diff --git a/src/images/SkImageDecoder_libbmp.cpp b/src/images/SkImageDecoder_libbmp.cpp
index 8683e21..fa75295 100644
--- a/src/images/SkImageDecoder_libbmp.cpp
+++ b/src/images/SkImageDecoder_libbmp.cpp
@@ -27,6 +27,10 @@
     virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
 };
 
+///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(BMPImageDecoder);
+///////////////////////////////////////////////////////////////////////////////
+
 SkImageDecoder* sk_libbmp_dfactory(SkStream* stream) {
     static const char kBmpMagic[] = { 'B', 'M' };
     
diff --git a/src/images/SkImageDecoder_libgif.cpp b/src/images/SkImageDecoder_libgif.cpp
index 3bc33c3..cd4ee22 100644
--- a/src/images/SkImageDecoder_libgif.cpp
+++ b/src/images/SkImageDecoder_libgif.cpp
@@ -327,6 +327,8 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(GIFImageDecoder);
+///////////////////////////////////////////////////////////////////////////////
 
 #include "SkTRegistry.h"
 
diff --git a/src/images/SkImageDecoder_libico.cpp b/src/images/SkImageDecoder_libico.cpp
index 226c84a..3473344 100644
--- a/src/images/SkImageDecoder_libico.cpp
+++ b/src/images/SkImageDecoder_libico.cpp
@@ -366,6 +366,8 @@
     *address = SkPreMultiplyARGB(alpha, red, green, blue);
 }
 
+///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(ICOImageDecoder);
 /////////////////////////////////////////////////////////////////////////////////////////
 
 #include "SkTRegistry.h"
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index 5cb45a2..8bc6f3d 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -653,11 +653,14 @@
 };
 
 ///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(JPEGImageDecoder);
+DEFINE_ENCODER_CREATOR(JPEGImageEncoder);
+///////////////////////////////////////////////////////////////////////////////
 
 #include "SkTRegistry.h"
 
 SkImageDecoder* sk_libjpeg_dfactory(SkStream* stream) {
-    static const char gHeader[] = { 0xFF, 0xD8, 0xFF };
+    static const unsigned char gHeader[] = { 0xFF, 0xD8, 0xFF };
     static const size_t HEADER_SIZE = sizeof(gHeader);
 
     char buffer[HEADER_SIZE];
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
index cefbe5e..8fe3423 100644
--- a/src/images/SkImageDecoder_libpng.cpp
+++ b/src/images/SkImageDecoder_libpng.cpp
@@ -852,6 +852,9 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(PNGImageDecoder);
+DEFINE_ENCODER_CREATOR(PNGImageEncoder);
+///////////////////////////////////////////////////////////////////////////////
 
 #include "SkTRegistry.h"
 
diff --git a/src/images/SkImageDecoder_wbmp.cpp b/src/images/SkImageDecoder_wbmp.cpp
index 262cf54..28a3705 100644
--- a/src/images/SkImageDecoder_wbmp.cpp
+++ b/src/images/SkImageDecoder_wbmp.cpp
@@ -148,6 +148,8 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(WBMPImageDecoder);
+///////////////////////////////////////////////////////////////////////////////
 
 #include "SkTRegistry.h"