1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 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 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkImageDecoder.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBitmap.h" 11f8d7d2731318cdf510ab68e6b3f5ec68ab22c8e2scroggo@google.com#include "SkImagePriv.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPixelRef.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 15a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkCanvas.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkImageDecoder::SkImageDecoder() 187e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com : fPeeker(NULL) 197e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com , fAllocator(NULL) 207e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com , fSampleSize(1) 21bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed , fDefaultPref(kUnknown_SkColorType) 22be08aceaab724b21136d7654fa86315850e9993creed , fPreserveSrcDepth(false) 237e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com , fDitherImage(true) 248d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com , fSkipWritingZeroes(false) 252bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com , fPreferQualityOverSpeed(false) 262bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com , fRequireUnpremultipliedColors(false) { 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkImageDecoder::~SkImageDecoder() { 3082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fPeeker); 3182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fAllocator); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34468142b2f50de055f00d5684515d962777da5131scroggo@google.comvoid SkImageDecoder::copyFieldsToOther(SkImageDecoder* other) { 35468142b2f50de055f00d5684515d962777da5131scroggo@google.com if (NULL == other) { 36468142b2f50de055f00d5684515d962777da5131scroggo@google.com return; 37468142b2f50de055f00d5684515d962777da5131scroggo@google.com } 38468142b2f50de055f00d5684515d962777da5131scroggo@google.com other->setPeeker(fPeeker); 39468142b2f50de055f00d5684515d962777da5131scroggo@google.com other->setAllocator(fAllocator); 40468142b2f50de055f00d5684515d962777da5131scroggo@google.com other->setSampleSize(fSampleSize); 41be08aceaab724b21136d7654fa86315850e9993creed other->setPreserveSrcDepth(fPreserveSrcDepth); 428d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com other->setDitherImage(fDitherImage); 438d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com other->setSkipWritingZeroes(fSkipWritingZeroes); 44468142b2f50de055f00d5684515d962777da5131scroggo@google.com other->setPreferQualityOverSpeed(fPreferQualityOverSpeed); 45468142b2f50de055f00d5684515d962777da5131scroggo@google.com other->setRequireUnpremultipliedColors(fRequireUnpremultipliedColors); 46468142b2f50de055f00d5684515d962777da5131scroggo@google.com} 47468142b2f50de055f00d5684515d962777da5131scroggo@google.com 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkImageDecoder::Format SkImageDecoder::getFormat() const { 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return kUnknown_Format; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 52a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgconst char* SkImageDecoder::getFormatName() const { 53f98118e65cbcee064bb8034f94a4faf4ea8d5536scroggo@google.com return GetFormatName(this->getFormat()); 54f98118e65cbcee064bb8034f94a4faf4ea8d5536scroggo@google.com} 55f98118e65cbcee064bb8034f94a4faf4ea8d5536scroggo@google.com 56f98118e65cbcee064bb8034f94a4faf4ea8d5536scroggo@google.comconst char* SkImageDecoder::GetFormatName(Format format) { 57f98118e65cbcee064bb8034f94a4faf4ea8d5536scroggo@google.com switch (format) { 5839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case kUnknown_Format: 5939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return "Unknown Format"; 6039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case kBMP_Format: 6139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return "BMP"; 6239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case kGIF_Format: 6339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return "GIF"; 6439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case kICO_Format: 6539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return "ICO"; 668cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com case kPKM_Format: 678cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com return "PKM"; 6899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski case kKTX_Format: 6999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski return "KTX"; 7095b1b3d82d227141647777d83324aa570b530096krajcevski case kASTC_Format: 7195b1b3d82d227141647777d83324aa570b530096krajcevski return "ASTC"; 7239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case kJPEG_Format: 7339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return "JPEG"; 7439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case kPNG_Format: 7539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return "PNG"; 7639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case kWBMP_Format: 7739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return "WBMP"; 7839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case kWEBP_Format: 7939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return "WEBP"; 8039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com default: 81330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com SkDEBUGFAIL("Invalid format type!"); 8239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 8339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return "Unknown Format"; 84a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 85a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fPeeker, peeker); 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return peeker; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) { 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fAllocator, alloc); 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return alloc; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkImageDecoder::setSampleSize(int size) { 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (size < 1) { 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size = 1; 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSampleSize = size; 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkImageDecoder::allocPixelRef(SkBitmap* bitmap, 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkColorTable* ctable) const { 105848250415eddc54075f7eb8795e8db79e749c6abreed return bitmap->tryAllocPixels(fAllocator, ctable); 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 109b6137c3139b1b1da99ad9f6c28ac0d9e8f910ff6reed@android.com 1106c22573edb234ad14df947278cfed010669a39a7reedSkColorType SkImageDecoder::getPrefColorType(SrcDepth srcDepth, bool srcHasAlpha) const { 111bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed SkColorType ct = fDefaultPref; 112be08aceaab724b21136d7654fa86315850e9993creed if (fPreserveSrcDepth) { 113be08aceaab724b21136d7654fa86315850e9993creed switch (srcDepth) { 114be08aceaab724b21136d7654fa86315850e9993creed case kIndex_SrcDepth: 115be08aceaab724b21136d7654fa86315850e9993creed ct = kIndex_8_SkColorType; 116be08aceaab724b21136d7654fa86315850e9993creed break; 117be08aceaab724b21136d7654fa86315850e9993creed case k8BitGray_SrcDepth: 118be08aceaab724b21136d7654fa86315850e9993creed ct = kN32_SkColorType; 119be08aceaab724b21136d7654fa86315850e9993creed break; 120be08aceaab724b21136d7654fa86315850e9993creed case k32Bit_SrcDepth: 121be08aceaab724b21136d7654fa86315850e9993creed ct = kN32_SkColorType; 122be08aceaab724b21136d7654fa86315850e9993creed break; 123be08aceaab724b21136d7654fa86315850e9993creed } 124be08aceaab724b21136d7654fa86315850e9993creed } 125bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed return ct; 1263f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com} 1273f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com 1282a1208017dd676f94a53bbb228197c3978dbdd8ascroggoSkImageDecoder::Result SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, SkColorType pref, 1292a1208017dd676f94a53bbb228197c3978dbdd8ascroggo Mode mode) { 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we reset this to false before calling onDecode 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fShouldCancelDecode = false; 132bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed // assign this, for use by getPrefColorType(), in case fUsePrefTable is false 1333f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com fDefaultPref = pref; 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 135a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // pass a temporary bitmap, so that if we return false, we are assured of 136a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // leaving the caller's bitmap untouched. 1372a1208017dd676f94a53bbb228197c3978dbdd8ascroggo SkBitmap tmp; 1382a1208017dd676f94a53bbb228197c3978dbdd8ascroggo const Result result = this->onDecode(stream, &tmp, mode); 1392a1208017dd676f94a53bbb228197c3978dbdd8ascroggo if (kFailure != result) { 1402a1208017dd676f94a53bbb228197c3978dbdd8ascroggo bm->swap(tmp); 14162900b4c64401bc80ae85f6f5c87309a273cae10reed@android.com } 1422a1208017dd676f94a53bbb228197c3978dbdd8ascroggo return result; 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 145bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereedbool SkImageDecoder::decodeSubset(SkBitmap* bm, const SkIRect& rect, SkColorType pref) { 1467e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com // we reset this to false before calling onDecodeSubset 147a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fShouldCancelDecode = false; 148bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed // assign this, for use by getPrefColorType(), in case fUsePrefTable is false 149a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fDefaultPref = pref; 150a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 1517e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com return this->onDecodeSubset(bm, rect); 152a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 153a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 154bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereedbool SkImageDecoder::buildTileIndex(SkStreamRewindable* stream, int *width, int *height) { 155a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // we reset this to false before calling onBuildTileIndex 156a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fShouldCancelDecode = false; 157a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 158a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return this->onBuildTileIndex(stream, width, height); 159a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 160a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 161a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggobool SkImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int* /*width*/, 162a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo int* /*height*/) { 163a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo SkDELETE(stream); 164a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo return false; 165a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo} 166a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo 167a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo 1687e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.combool SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, 1697e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com int dstX, int dstY, int width, int height, 1707e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com int srcX, int srcY) { 171a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int w = width / sampleSize; 172a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int h = height / sampleSize; 1730689d7b12e7c427a077b003d3d8ae759d86f798freed if (src->colorType() == kIndex_8_SkColorType) { 1747e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com // kIndex8 does not allow drawing via an SkCanvas, as is done below. 1757e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com // Instead, use extractSubset. Note that this shares the SkPixelRef and 1767e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com // SkColorTable. 1777e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com // FIXME: Since src is discarded in practice, this holds on to more 1787e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com // pixels than is strictly necessary. Switch to a copy if memory 1797e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com // savings are more important than speed here. This also means 1807e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com // that the pixels in dst can not be reused (though there is no 1817e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com // allocation, which was already done on src). 1827e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com int x = (dstX - srcX) / sampleSize; 1837e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com int y = (dstY - srcY) / sampleSize; 1847e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com SkIRect subset = SkIRect::MakeXYWH(x, y, w, h); 1857e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com return src->extractSubset(dst, subset); 1867e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com } 187a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // if the destination has no pixels then we must allocate them. 188a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (dst->isNull()) { 1896c22573edb234ad14df947278cfed010669a39a7reed dst->setInfo(src->info().makeWH(w, h)); 190a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 191a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!this->allocPixelRef(dst, NULL)) { 192a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkDEBUGF(("failed to allocate pixels needed to crop the bitmap")); 1937e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com return false; 194a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 195a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 196a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // check to see if the destination is large enough to decode the desired 197a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // region. If this assert fails we will just draw as much of the source 198a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // into the destination that we can. 1997e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com if (dst->width() < w || dst->height() < h) { 2007e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com SkDEBUGF(("SkImageDecoder::cropBitmap does not have a large enough bitmap.\n")); 2017e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com } 202a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 203a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // Set the Src_Mode for the paint to prevent transparency issue in the 204a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // dest in the event that the dest was being re-used. 205a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkPaint paint; 206a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org paint.setXfermodeMode(SkXfermode::kSrc_Mode); 207a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 208a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkCanvas canvas(*dst); 209a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org canvas.drawSprite(*src, (srcX - dstX) / sampleSize, 210a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org (srcY - dstY) / sampleSize, 211a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org &paint); 2127e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com return true; 213a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 214a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 217bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereedbool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, SkColorType pref, Mode mode, 218bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed Format* format) { 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(file); 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(bm); 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 222a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo SkAutoTDelete<SkStreamRewindable> stream(SkStream::NewFromFile(file)); 223f381162e5616daacdbcc06d693aca5111aeeebe8mike@reedtribe.org if (stream.get()) { 224f381162e5616daacdbcc06d693aca5111aeeebe8mike@reedtribe.org if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) { 225dedc2d8e8dc635ff43e6b314b280e3efe85ce8a7reed if (SkPixelRef* pr = bm->pixelRef()) { 226dedc2d8e8dc635ff43e6b314b280e3efe85ce8a7reed pr->setURI(file); 227dedc2d8e8dc635ff43e6b314b280e3efe85ce8a7reed } 2281a366217cd7a9833756fe1b53c59053d6621f4bctomhudson@google.com return true; 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 234bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereedbool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, SkColorType pref, 235bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed Mode mode, Format* format) { 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == size) { 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(buffer); 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMemoryStream stream(buffer, size); 242b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format); 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 245bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereedbool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm, SkColorType pref, 246bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed Mode mode, Format* format) { 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(stream); 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(bm); 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = false; 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkImageDecoder* codec = SkImageDecoder::Factory(stream); 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25349f085dddff10473b6ebf832a974288300224e60bsalomon if (codec) { 2542a1208017dd676f94a53bbb228197c3978dbdd8ascroggo success = codec->decode(stream, bm, pref, mode) != kFailure; 255b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com if (success && format) { 256b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com *format = codec->getFormat(); 25739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (kUnknown_Format == *format) { 25839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (stream->rewind()) { 25939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com *format = GetStreamFormat(stream); 26039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 26139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 262b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com } 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete codec; 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return success; 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 267b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi 268b227e37eae36ccf630c4baef00b1354d42b40fd1sugoibool SkImageDecoder::decodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], void* planes[3], 269b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi size_t rowBytes[3], SkYUVColorSpace* colorSpace) { 270b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi // we reset this to false before calling onDecodeYUV8Planes 271b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi fShouldCancelDecode = false; 272b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi 273b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi return this->onDecodeYUV8Planes(stream, componentSizes, planes, rowBytes, colorSpace); 274b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi} 275