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 SkStreamRewindable. 16 17 template SkImageDecoder_DecodeReg* SkImageDecoder_DecodeReg::gHead; 18 19 SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*); 20 21 SkImageDecoder* image_decoder_from_stream(SkStreamRewindable* stream) { 22 SkImageDecoder* codec = nullptr; 23 const SkImageDecoder_DecodeReg* curr = SkImageDecoder_DecodeReg::Head(); 24 while (curr) { 25 codec = curr->factory()(stream); 26 // we rewind here, because we promise later when we call "decode", that 27 // the stream will be at its beginning. 28 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 delete codec; 35 return nullptr; 36 } 37 38 if (codec) { 39 return codec; 40 } 41 curr = curr->next(); 42 } 43 return nullptr; 44 } 45 46 template SkImageDecoder_FormatReg* SkImageDecoder_FormatReg::gHead; 47 48 SkImageDecoder::Format SkImageDecoder::GetStreamFormat(SkStreamRewindable* stream) { 49 const SkImageDecoder_FormatReg* curr = SkImageDecoder_FormatReg::Head(); 50 while (curr != nullptr) { 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 } 64