1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 24c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com * Copyright 2013 The Android Open Source Project 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com#include "SkErrorInternals.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkImageDecoder.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 1100bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com#include "SkTRegistry.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 134c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com// This file is used for registration of SkImageDecoders. It also holds a function 144c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com// for checking all the the registered SkImageDecoders for one that matches an 15b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com// input SkStreamRewindable. 164c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com 17bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.comtemplate SkImageDecoder_DecodeReg* SkImageDecoder_DecodeReg::gHead; 183c2b7e8b5e718192e9c944b2c79189e2ee227606reed@android.com 19b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comSkImageDecoder* image_decoder_from_stream(SkStreamRewindable*); 204c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com 21b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comSkImageDecoder* image_decoder_from_stream(SkStreamRewindable* stream) { 22dfee579a8de6462399f1b1867f924856c11bc4a1reed@android.com SkImageDecoder* codec = NULL; 23bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com const SkImageDecoder_DecodeReg* curr = SkImageDecoder_DecodeReg::Head(); 2400bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com while (curr) { 25dfee579a8de6462399f1b1867f924856c11bc4a1reed@android.com codec = curr->factory()(stream); 26a16cb97c89fedcd521aeaadfa94feddbcb6729b1reed@android.com // we rewind here, because we promise later when we call "decode", that 27a16cb97c89fedcd521aeaadfa94feddbcb6729b1reed@android.com // the stream will be at its beginning. 2850166524abd948f6288089c572cf125d2b4827a7djsollen@google.com bool rewindSuceeded = stream->rewind(); 2950166524abd948f6288089c572cf125d2b4827a7djsollen@google.com 3050166524abd948f6288089c572cf125d2b4827a7djsollen@google.com // our image decoder's require that rewind is supported so we fail early 3150166524abd948f6288089c572cf125d2b4827a7djsollen@google.com // if we are given a stream that does not support rewinding. 3250166524abd948f6288089c572cf125d2b4827a7djsollen@google.com if (!rewindSuceeded) { 3350166524abd948f6288089c572cf125d2b4827a7djsollen@google.com SkDEBUGF(("Unable to rewind the image stream.")); 3450166524abd948f6288089c572cf125d2b4827a7djsollen@google.com SkDELETE(codec); 3550166524abd948f6288089c572cf125d2b4827a7djsollen@google.com return NULL; 3650166524abd948f6288089c572cf125d2b4827a7djsollen@google.com } 3750166524abd948f6288089c572cf125d2b4827a7djsollen@google.com 3800bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com if (codec) { 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return codec; 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4100bf85a98675c9d0c3150bbeb0a3d7198ad8f21freed@android.com curr = curr->next(); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 46bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.comtemplate SkImageDecoder_FormatReg* SkImageDecoder_FormatReg::gHead; 4739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 48b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comSkImageDecoder::Format SkImageDecoder::GetStreamFormat(SkStreamRewindable* stream) { 49bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com const SkImageDecoder_FormatReg* curr = SkImageDecoder_FormatReg::Head(); 5039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com while (curr != NULL) { 5139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com Format format = curr->factory()(stream); 5239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (!stream->rewind()) { 5339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com SkErrorInternals::SetError(kInvalidOperation_SkError, 5439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com "Unable to rewind the image stream\n"); 5539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return kUnknown_Format; 5639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 5739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (format != kUnknown_Format) { 5839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return format; 5939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 6039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com curr = curr->next(); 6139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 6239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return kUnknown_Format; 6339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com} 64