blob: b47a6d5317dca15c71d83edcfe367363f9c4bdef [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
scroggo@google.com4c6adf92013-04-17 21:07:55 +00002 * Copyright 2013 The Android Open Source Project
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
scroggo@google.com39edf4c2013-04-25 17:33:51 +00008#include "SkErrorInternals.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +00009#include "SkImageDecoder.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#include "SkStream.h"
reed@android.com00bf85a2009-01-22 13:04:56 +000011#include "SkTRegistry.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000012
scroggo@google.com4c6adf92013-04-17 21:07:55 +000013// This file is used for registration of SkImageDecoders. It also holds a function
14// for checking all the the registered SkImageDecoders for one that matches an
scroggo@google.comb5571b32013-09-25 21:34:24 +000015// input SkStreamRewindable.
scroggo@google.com4c6adf92013-04-17 21:07:55 +000016
mtklein@google.combd6343b2013-09-04 17:20:18 +000017template SkImageDecoder_DecodeReg* SkImageDecoder_DecodeReg::gHead;
reed@android.com3c2b7e82009-01-27 01:43:36 +000018
scroggo@google.comb5571b32013-09-25 21:34:24 +000019SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*);
scroggo@google.com4c6adf92013-04-17 21:07:55 +000020
scroggo@google.comb5571b32013-09-25 21:34:24 +000021SkImageDecoder* image_decoder_from_stream(SkStreamRewindable* stream) {
reed@android.comdfee5792010-04-15 14:24:50 +000022 SkImageDecoder* codec = NULL;
mtklein@google.combd6343b2013-09-04 17:20:18 +000023 const SkImageDecoder_DecodeReg* curr = SkImageDecoder_DecodeReg::Head();
reed@android.com00bf85a2009-01-22 13:04:56 +000024 while (curr) {
reed@android.comdfee5792010-04-15 14:24:50 +000025 codec = curr->factory()(stream);
reed@android.coma16cb972009-06-18 20:26:58 +000026 // we rewind here, because we promise later when we call "decode", that
27 // the stream will be at its beginning.
djsollen@google.com50166522013-03-20 20:16:20 +000028 bool rewindSuceeded = stream->rewind();
29
30 // our image decoder's require that rewind is supported so we fail early
31 // if we are given a stream that does not support rewinding.
32 if (!rewindSuceeded) {
33 SkDEBUGF(("Unable to rewind the image stream."));
34 SkDELETE(codec);
35 return NULL;
36 }
37
reed@android.com00bf85a2009-01-22 13:04:56 +000038 if (codec) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000039 return codec;
40 }
reed@android.com00bf85a2009-01-22 13:04:56 +000041 curr = curr->next();
reed@android.com8a1c16f2008-12-17 15:59:43 +000042 }
43 return NULL;
44}
scroggo@google.com39edf4c2013-04-25 17:33:51 +000045
mtklein@google.combd6343b2013-09-04 17:20:18 +000046template SkImageDecoder_FormatReg* SkImageDecoder_FormatReg::gHead;
scroggo@google.com39edf4c2013-04-25 17:33:51 +000047
scroggo@google.comb5571b32013-09-25 21:34:24 +000048SkImageDecoder::Format SkImageDecoder::GetStreamFormat(SkStreamRewindable* stream) {
mtklein@google.combd6343b2013-09-04 17:20:18 +000049 const SkImageDecoder_FormatReg* curr = SkImageDecoder_FormatReg::Head();
scroggo@google.com39edf4c2013-04-25 17:33:51 +000050 while (curr != NULL) {
51 Format format = curr->factory()(stream);
52 if (!stream->rewind()) {
53 SkErrorInternals::SetError(kInvalidOperation_SkError,
54 "Unable to rewind the image stream\n");
55 return kUnknown_Format;
56 }
57 if (format != kUnknown_Format) {
58 return format;
59 }
60 curr = curr->next();
61 }
62 return kUnknown_Format;
63}