diff options
author | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-01-22 13:04:56 +0000 |
---|---|---|
committer | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-01-22 13:04:56 +0000 |
commit | 00bf85a98675c9d0c3150bbeb0a3d7198ad8f21f (patch) | |
tree | b4b522fd859aa3e3dcc2f20061bddbe348b850e4 | |
parent | 9db6087c0e8be71e50aa09106759a868cb9597dc (diff) |
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
-rw-r--r-- | include/core/SkTRegistry.h | 50 | ||||
-rw-r--r-- | include/images/SkImageDecoder.h | 6 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libbmp.cpp | 6 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libgif.cpp | 5 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libico.cpp | 38 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libjpeg.cpp | 50 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libpng.cpp | 29 | ||||
-rw-r--r-- | src/images/SkImageDecoder_wbmp.cpp | 25 | ||||
-rw-r--r-- | src/ports/SkImageDecoder_CG.cpp | 4 | ||||
-rw-r--r-- | src/ports/SkImageDecoder_Factory.cpp | 57 | ||||
-rw-r--r-- | src/ports/SkImageEncoder_Factory.cpp | 19 |
11 files changed, 155 insertions, 134 deletions
diff --git a/include/core/SkTRegistry.h b/include/core/SkTRegistry.h new file mode 100644 index 0000000000..83c08de171 --- /dev/null +++ b/include/core/SkTRegistry.h @@ -0,0 +1,50 @@ +/* + * Copyright 2009, 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 + * + * 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 + * limitations under the License. + */ + +#ifndef SkTRegistry_DEFINED +#define SkTRegistry_DEFINED + +#include "SkTypes.h" + +/** Template class that registers itself (in the constructor) into a linked-list + and provides a function-pointer. This can be used to auto-register a set of + services, e.g. a set of image codecs. + */ +template <typename T, typename P> class SkTRegistry : SkNoncopyable { +public: + typedef T (*Factory)(P); + + SkTRegistry(Factory fact) { + fFact = fact; + fChain = gHead; + gHead = this; + } + + static const SkTRegistry* Head() { return gHead; } + + const SkTRegistry* next() const { return fChain; } + Factory factory() const { return fFact; } + +private: + Factory fFact; + SkTRegistry* fChain; + + static SkTRegistry* gHead; +}; + +template <typename T, typename P> SkTRegistry<T, P>* SkTRegistry<T, P>::gHead; + +#endif diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h index 5b91c51fdd..3ea6198e33 100644 --- a/include/images/SkImageDecoder.h +++ b/include/images/SkImageDecoder.h @@ -199,12 +199,6 @@ public: kDecodePixels_Mode); } - /* Given a format, return true if there is a currently installed decoder - for that format. Since a given build may not include all codecs (to save - code-size), this may return false. - */ - static bool SupportsFormat(Format); - /** 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. diff --git a/src/images/SkImageDecoder_libbmp.cpp b/src/images/SkImageDecoder_libbmp.cpp index 32a7a6de42..a4dcbf6174 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 @@ protected: 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 @@ SkImageDecoder* SkImageDecoder_BMP_Factory(SkStream* stream) { 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 519366a18e..ed8817ab86 100644 --- a/src/images/SkImageDecoder_libgif.cpp +++ b/src/images/SkImageDecoder_libgif.cpp @@ -326,7 +326,9 @@ DONE: /////////////////////////////////////////////////////////////////////////////// -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 @@ SkImageDecoder* SkImageDecoder_GIF_Factory(SkStream* stream) { return NULL; } +static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory); diff --git a/src/images/SkImageDecoder_libico.cpp b/src/images/SkImageDecoder_libico.cpp index b179a6b61a..9f21e13256 100644 --- a/src/images/SkImageDecoder_libico.cpp +++ b/src/images/SkImageDecoder_libico.cpp @@ -44,23 +44,6 @@ protected: ///////////////////////////////////////////////////////////////////////////////////////// -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 @@ static void editPixelBit32(const int pixelNo, const unsigned char* buf, *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 51339971ac..018c96c353 100644 --- a/src/images/SkImageDecoder_libjpeg.cpp +++ b/src/images/SkImageDecoder_libjpeg.cpp @@ -51,24 +51,6 @@ protected: 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 @@ protected: } }; -SkImageEncoder* SkImageEncoder_JPEG_Factory(); -SkImageEncoder* SkImageEncoder_JPEG_Factory() { - return SkNEW(SkJPEGImageEncoder); -} +/////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// +#include "SkTRegistry.h" -#ifdef SK_DEBUG +static SkImageDecoder* DFactory(SkStream* stream) { + static const char gHeader[] = { 0xFF, 0xD8, 0xFF }; + static const size_t HEADER_SIZE = sizeof(gHeader); -void SkImageDecoder::UnitTest() { - SkBitmap bm; + 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); +} - (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 fedb8df19f..b616eee918 100644 --- a/src/images/SkImageDecoder_libpng.cpp +++ b/src/images/SkImageDecoder_libpng.cpp @@ -58,15 +58,6 @@ private: 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 @@ bool SkPNGImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bitmap, 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 9d188f6016..ac242ea22f 100644 --- a/src/images/SkImageDecoder_wbmp.cpp +++ b/src/images/SkImageDecoder_wbmp.cpp @@ -77,16 +77,6 @@ struct wbmp_head { } }; -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 @@ bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, 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); + diff --git a/src/ports/SkImageDecoder_CG.cpp b/src/ports/SkImageDecoder_CG.cpp index 5594eac91a..7f8b26c2c5 100644 --- a/src/ports/SkImageDecoder_CG.cpp +++ b/src/ports/SkImageDecoder_CG.cpp @@ -94,10 +94,6 @@ SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) { return SkNEW(SkImageDecoder_CG); } -bool SkImageDecoder::SupportsFormat(Format format) { - return true; -} - ///////////////////////////////////////////////////////////////////////// SkMovie* SkMovie::DecodeStream(SkStream* stream) { diff --git a/src/ports/SkImageDecoder_Factory.cpp b/src/ports/SkImageDecoder_Factory.cpp index 5c45a43ec5..33009812fd 100644 --- a/src/ports/SkImageDecoder_Factory.cpp +++ b/src/ports/SkImageDecoder_Factory.cpp @@ -18,67 +18,36 @@ #include "SkImageDecoder.h" #include "SkMovie.h" #include "SkStream.h" +#include "SkTRegistry.h" -extern SkImageDecoder* SkImageDecoder_GIF_Factory(SkStream*); -extern SkImageDecoder* SkImageDecoder_BMP_Factory(SkStream*); -extern SkImageDecoder* SkImageDecoder_ICO_Factory(SkStream*); -extern SkImageDecoder* SkImageDecoder_PNG_Factory(SkStream*); -extern SkImageDecoder* SkImageDecoder_WBMP_Factory(SkStream*); -extern SkImageDecoder* SkImageDecoder_JPEG_Factory(SkStream*); - -typedef SkImageDecoder* (*SkImageDecoderFactoryProc)(SkStream*); - -struct CodecFormat { - SkImageDecoderFactoryProc fProc; - SkImageDecoder::Format fFormat; -}; - -static const CodecFormat gPairs[] = { - { SkImageDecoder_GIF_Factory, SkImageDecoder::kGIF_Format }, - { SkImageDecoder_PNG_Factory, SkImageDecoder::kPNG_Format }, - { SkImageDecoder_ICO_Factory, SkImageDecoder::kICO_Format }, - { SkImageDecoder_WBMP_Factory, SkImageDecoder::kWBMP_Format }, - { SkImageDecoder_BMP_Factory, SkImageDecoder::kBMP_Format }, - { SkImageDecoder_JPEG_Factory, SkImageDecoder::kJPEG_Format } -}; +typedef SkTRegistry<SkImageDecoder*, SkStream*> DecodeReg; SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) { - for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { - SkImageDecoder* codec = gPairs[i].fProc(stream); + const DecodeReg* curr = DecodeReg::Head(); + while (curr) { + SkImageDecoder* codec = curr->factory()(stream); stream->rewind(); - if (NULL != codec) { + if (codec) { return codec; } + curr = curr->next(); } return NULL; } -bool SkImageDecoder::SupportsFormat(Format format) { - for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { - if (gPairs[i].fFormat == format) { - return true; - } - } - return false; -} - ///////////////////////////////////////////////////////////////////////// -typedef SkMovie* (*SkMovieFactoryProc)(SkStream*); - -extern SkMovie* SkMovie_GIF_Factory(SkStream*); - -static const SkMovieFactoryProc gMovieProcs[] = { - SkMovie_GIF_Factory -}; +typedef SkTRegistry<SkMovie*, SkStream*> MovieReg; SkMovie* SkMovie::DecodeStream(SkStream* stream) { - for (unsigned i = 0; i < SK_ARRAY_COUNT(gMovieProcs); i++) { - SkMovie* movie = gMovieProcs[i](stream); - if (NULL != movie) { + const MovieReg* curr = MovieReg::Head(); + while (curr) { + SkMovie* movie = curr->factory()(stream); + if (movie) { return movie; } stream->rewind(); + curr = curr->next(); } return NULL; } diff --git a/src/ports/SkImageEncoder_Factory.cpp b/src/ports/SkImageEncoder_Factory.cpp index cdd7c0409f..f44cd8fa30 100644 --- a/src/ports/SkImageEncoder_Factory.cpp +++ b/src/ports/SkImageEncoder_Factory.cpp @@ -15,18 +15,19 @@ */ #include "SkImageEncoder.h" +#include "SkTRegistry.h" -extern SkImageEncoder* SkImageEncoder_JPEG_Factory(); -extern SkImageEncoder* SkImageEncoder_PNG_Factory(); +typedef SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> EncodeReg; SkImageEncoder* SkImageEncoder::Create(Type t) { - switch (t) { - case kJPEG_Type: - return SkImageEncoder_JPEG_Factory(); - case kPNG_Type: - return SkImageEncoder_PNG_Factory(); - default: - return NULL; + const EncodeReg* curr = EncodeReg::Head(); + while (curr) { + SkImageEncoder* codec = curr->factory()(t); + if (codec) { + return codec; + } + curr = curr->next(); } + return NULL; } |