1/* 2 * Copyright 2013 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkErrorInternals.h" 9#include "SkImageDecoder.h" 10#include "SkStream.h" 11#include "SkTRegistry.h" 12 13// 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 15// input SkStream. 16 17typedef SkTRegistry<SkImageDecoder*, SkStream*> DecodeReg; 18 19// N.B. You can't use "DecodeReg::gHead here" due to complex C++ 20// corner cases. 21template DecodeReg* SkTRegistry<SkImageDecoder*, SkStream*>::gHead; 22 23SkImageDecoder* image_decoder_from_stream(SkStream*); 24 25SkImageDecoder* image_decoder_from_stream(SkStream* stream) { 26 SkImageDecoder* codec = NULL; 27 const DecodeReg* curr = DecodeReg::Head(); 28 while (curr) { 29 codec = curr->factory()(stream); 30 // we rewind here, because we promise later when we call "decode", that 31 // the stream will be at its beginning. 32 bool rewindSuceeded = stream->rewind(); 33 34 // our image decoder's require that rewind is supported so we fail early 35 // if we are given a stream that does not support rewinding. 36 if (!rewindSuceeded) { 37 SkDEBUGF(("Unable to rewind the image stream.")); 38 SkDELETE(codec); 39 return NULL; 40 } 41 42 if (codec) { 43 return codec; 44 } 45 curr = curr->next(); 46 } 47 return NULL; 48} 49 50typedef SkTRegistry<SkImageDecoder::Format, SkStream*> FormatReg; 51 52template FormatReg* SkTRegistry<SkImageDecoder::Format, SkStream*>::gHead; 53 54SkImageDecoder::Format SkImageDecoder::GetStreamFormat(SkStream* stream) { 55 const FormatReg* curr = FormatReg::Head(); 56 while (curr != NULL) { 57 Format format = curr->factory()(stream); 58 if (!stream->rewind()) { 59 SkErrorInternals::SetError(kInvalidOperation_SkError, 60 "Unable to rewind the image stream\n"); 61 return kUnknown_Format; 62 } 63 if (format != kUnknown_Format) { 64 return format; 65 } 66 curr = curr->next(); 67 } 68 return kUnknown_Format; 69} 70