| Index: src/images/SkImageDecoder_Factory.cpp
|
| diff --git a/src/images/SkImageDecoder_Factory.cpp b/src/images/SkImageDecoder_Factory.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..457ec72e1d37cec8dd807ab1d7c40c03fdc65922
|
| --- /dev/null
|
| +++ b/src/images/SkImageDecoder_Factory.cpp
|
| @@ -0,0 +1,128 @@
|
| +/*
|
| + * Copyright 2014 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SkErrorInternals.h"
|
| +#include "SkImageDecoder.h"
|
| +#include "SkImageDecoder_libjpeg.h"
|
| +#include "SkImageDecoder_libwebp.h"
|
| +#include "SkImageDecoder_libico.h"
|
| +#include "SkImageDecoder_libbmp.h"
|
| +#include "SkImageDecoder_wbmp.h"
|
| +#include "SkMovie.h"
|
| +#include "SkStream.h"
|
| +
|
| +#if defined(SK_BUILD_FOR_WIN)
|
| +#include "SkImageDecoder_WIC.h"
|
| +#endif
|
| +#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
|
| +#include "SkImageDecoder_CG.h"
|
| +#endif
|
| +#if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_WIN)
|
| +#include "SkImageDecoder_libpng.h"
|
| +#endif
|
| +#if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_WIN) && \
|
| + !defined(SK_BUILD_FOR_NACL)
|
| +#include "SkImageDecoder_libgif.h"
|
| +#include "SkMovie_gif.h"
|
| +#endif
|
| +#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
|
| +#include "SkImageDecoder_astc.h"
|
| +#include "SkImageDecoder_ktx.h"
|
| +#include "SkImageDecoder_pkm.h"
|
| +#endif
|
| +
|
| +// 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 SkStreamRewindable.
|
| +
|
| +// The order of the factory functions defines the order image decoders are tested when decoding a
|
| +// stream. The first function is the first one tested, so the functions should be listed in order
|
| +// from the most likely to be used, to the least likely. JPEG and PNG should be the first two, for
|
| +// instance.
|
| +
|
| +typedef SkImageDecoder* (*FactoryCreateFunc)(SkImageDecoder::Format);
|
| +typedef SkImageDecoder::Format (*FactoryDetectFormatFunc)(SkStreamRewindable*);
|
| +static const struct {
|
| + const FactoryCreateFunc createFunc;
|
| + const FactoryDetectFormatFunc detectFormatFunc;
|
| +} gDecoderFactoryFuncs[] = {
|
| +#if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_WIN)
|
| + { SkCreatePNGImageDecoder, SkDetectFormatPNGImageDecoder },
|
| +#endif
|
| + { SkCreateJPEGImageDecoder, SkDetectFormatJPEGImageDecoder },
|
| + { SkCreateWEBPImageDecoder, SkDetectFormatWEBPImageDecoder },
|
| + { SkCreateICOImageDecoder, SkDetectFormatICOImageDecoder },
|
| +#if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_WIN) && \
|
| + !defined(SK_BUILD_FOR_NACL)
|
| + { SkCreateGIFImageDecoder, SkDetectFormatGIFImageDecoder },
|
| +#endif
|
| + { SkCreateBMPImageDecoder, SkDetectFormatBMPImageDecoder },
|
| +#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
|
| + { SkCreateASTCImageDecoder, SkDetectFormatASTCImageDecoder },
|
| + { SkCreateKTXImageDecoder, SkDetectFormatKTXImageDecoder },
|
| + { SkCreatePKMImageDecoder, SkDetectFormatPKMImageDecoder },
|
| +#endif
|
| + { SkCreateWBMPImageDecoder, SkDetectFormatWBMPImageDecoder },
|
| +#if defined(SK_BUILD_FOR_WIN)
|
| + { SkCreateImageDecoder_WIC, SkDetectFormatImageDecoder_WIC }
|
| +#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
|
| + { SkCreateImageDecoder_CG, SkDetectFormatImageDecoder_CG }
|
| +#endif
|
| +};
|
| +
|
| +SkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable* stream) {
|
| + for (size_t i = 0; i < SK_ARRAY_COUNT(gDecoderFactoryFuncs); ++i) {
|
| + FactoryDetectFormatFunc detectFormatFunc = gDecoderFactoryFuncs[i].detectFormatFunc;
|
| + Format format = detectFormatFunc(stream);
|
| +
|
| + // We rewind here, because we promise later when we call "decode", that the stream will be
|
| + // at its beginning.
|
| + bool rewindSuceeded = stream->rewind();
|
| +
|
| + // Our image decoders require that rewind is supported so we fail early if we are given a
|
| + // stream that does not support rewinding.
|
| + if (!rewindSuceeded) {
|
| + SkDEBUGF(("Unable to rewind the image stream."));
|
| + return NULL;
|
| + }
|
| +
|
| + if (SkImageDecoder::kUnknown_Format != format) {
|
| + FactoryCreateFunc createFunc = gDecoderFactoryFuncs[i].createFunc;
|
| + SkImageDecoder* codec = createFunc(format);
|
| + SkASSERT(NULL != codec);
|
| + return codec;
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +SkImageDecoder::Format SkImageDecoder::GetStreamFormat(SkStreamRewindable* stream) {
|
| + for (size_t i = 0; i < SK_ARRAY_COUNT(gDecoderFactoryFuncs); ++i) {
|
| + FactoryDetectFormatFunc detectFormatFunc = gDecoderFactoryFuncs[i].detectFormatFunc;
|
| + Format format = detectFormatFunc(stream);
|
| + if (!stream->rewind()) {
|
| + SkErrorInternals::SetError(kInvalidOperation_SkError,
|
| + "Unable to rewind the image stream\n");
|
| + return kUnknown_Format;
|
| + }
|
| + if (format != kUnknown_Format) {
|
| + return format;
|
| + }
|
| + }
|
| + return kUnknown_Format;
|
| +}
|
| +
|
| +SkMovie* SkMovie::DecodeStream(SkStreamRewindable* stream) {
|
| + SkMovie* movie = NULL;
|
| +#if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_WIN) && \
|
| + !defined(SK_BUILD_FOR_NACL)
|
| + movie = SkGIFMovieCreate(stream);
|
| + if (NULL == movie) {
|
| + stream->rewind();
|
| + }
|
| +#endif
|
| + return movie;
|
| +}
|
|
|