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