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 17template SkImageDecoder_DecodeReg* SkImageDecoder_DecodeReg::gHead; 18 19SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*); 20 21SkImageDecoder* 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 46template SkImageDecoder_FormatReg* SkImageDecoder_FormatReg::gHead; 47 48SkImageDecoder::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