18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.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.
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkImageDecoder_DEFINED
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkImageDecoder_DEFINED
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBitmap.h"
12f8d7d2731318cdf510ab68e6b3f5ec68ab22c8e2scroggo@google.com#include "SkImage.h"
13cf98fa93116cf5efcc42d48c22fb4bd76896acdcscroggo#include "SkPngChunkReader.h"
14a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkRect.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRefCnt.h"
16bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com#include "SkTRegistry.h"
177def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com#include "SkTypes.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkStream;
20b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comclass SkStreamRewindable;
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkImageDecoder
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Base class for decoding compressed images into a SkBitmap
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
26e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.orgclass SkImageDecoder : SkNoncopyable {
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual ~SkImageDecoder();
2925e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
301dd3ea9d4523436578c86dc8d8f43d63fa188c01scroggo    // TODO (scroggo): Merge with SkEncodedFormat
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    enum Format {
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kUnknown_Format,
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kBMP_Format,
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kGIF_Format,
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kICO_Format,
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kJPEG_Format,
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kPNG_Format,
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kWBMP_Format,
39a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org        kWEBP_Format,
408cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.com        kPKM_Format,
4199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        kKTX_Format,
4295b1b3d82d227141647777d83324aa570b530096krajcevski        kASTC_Format,
4325e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
4499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        kLastKnownFormat = kKTX_Format,
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
4625e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
474c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com    /** Return the format of image this decoder can decode. If this decoder can decode multiple
484c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com        formats, kUnknown_Format will be returned.
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual Format getFormat() const;
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
52b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi    /** If planes or rowBytes is NULL, decodes the header and computes componentSizes
53b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi        for memory allocation.
54b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi        Otherwise, decodes the YUV planes into the provided image planes and
55b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi        updates componentSizes to the final image size.
56b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi        Returns whether the decoding was successful.
57b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi    */
58b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi    bool decodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], void* planes[3],
59b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi                          size_t rowBytes[3], SkYUVColorSpace*);
60b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi
61b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com    /** Return the format of the SkStreamRewindable or kUnknown_Format if it cannot be determined.
62b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com        Rewinds the stream before returning.
6339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com    */
64b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com    static Format GetStreamFormat(SkStreamRewindable*);
6539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com
66f98118e65cbcee064bb8034f94a4faf4ea8d5536scroggo@google.com    /** Return a readable string of the Format provided.
67f98118e65cbcee064bb8034f94a4faf4ea8d5536scroggo@google.com    */
68f98118e65cbcee064bb8034f94a4faf4ea8d5536scroggo@google.com    static const char* GetFormatName(Format);
69f98118e65cbcee064bb8034f94a4faf4ea8d5536scroggo@google.com
704c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com    /** Return a readable string of the value returned by getFormat().
71a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    */
72a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    const char* getFormatName() const;
73a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org
748d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com    /** Whether the decoder should skip writing zeroes to output if possible.
758d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com    */
768d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com    bool getSkipWritingZeroes() const { return fSkipWritingZeroes; }
778d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com
788d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com    /** Set to true if the decoder should skip writing any zeroes when
798d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com        creating the output image.
808d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com        This is a hint that may not be respected by the decoder.
818d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com        It should only be used if it is known that the memory to write
828d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com        to has already been set to 0; otherwise the resulting image will
838d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com        have garbage.
848d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com        This is ideal for images that contain a lot of completely transparent
858d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com        pixels, but may be a performance hit for an image that has only a
868d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com        few transparent pixels.
878d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com        The default is false.
888d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com    */
898d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com    void setSkipWritingZeroes(bool skip) { fSkipWritingZeroes = skip; }
908d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns true if the decoder should try to dither the resulting image.
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        The default setting is true.
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool getDitherImage() const { return fDitherImage; }
9525e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set to true if the the decoder should try to dither the resulting image.
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        The default setting is true.
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void setDitherImage(bool dither) { fDitherImage = dither; }
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
101a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    /** Returns true if the decoder should try to decode the
102a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org        resulting image to a higher quality even at the expense of
103a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org        the decoding speed.
104a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    */
105a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    bool getPreferQualityOverSpeed() const { return fPreferQualityOverSpeed; }
106a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org
107a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    /** Set to true if the the decoder should try to decode the
108a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org        resulting image to a higher quality even at the expense of
109a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org        the decoding speed.
110a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    */
111a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    void setPreferQualityOverSpeed(bool qualityOverSpeed) {
112a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org        fPreferQualityOverSpeed = qualityOverSpeed;
113a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    }
114a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org
1152bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com    /** Set to true to require the decoder to return a bitmap with unpremultiplied
1162bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com        colors. The default is false, meaning the resulting bitmap will have its
1172bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com        colors premultiplied.
1182bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com        NOTE: Passing true to this function may result in a bitmap which cannot
1192bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com        be properly used by Skia.
1202bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com    */
1212bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com    void setRequireUnpremultipliedColors(bool request) {
1222bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com        fRequireUnpremultipliedColors = request;
1232bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com    }
1242bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com
1252bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com    /** Returns true if the decoder will only return bitmaps with unpremultiplied
1262bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com        colors.
1272bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com    */
1282bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com    bool getRequireUnpremultipliedColors() const { return fRequireUnpremultipliedColors; }
1292bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com
130cf98fa93116cf5efcc42d48c22fb4bd76896acdcscroggo    SkPngChunkReader* getPeeker() const { return fPeeker; }
131cf98fa93116cf5efcc42d48c22fb4bd76896acdcscroggo    SkPngChunkReader* setPeeker(SkPngChunkReader*);
13225e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
133be08aceaab724b21136d7654fa86315850e9993creed    /**
134be08aceaab724b21136d7654fa86315850e9993creed     *  By default, the codec will try to comply with the "pref" colortype
135be08aceaab724b21136d7654fa86315850e9993creed     *  that is passed to decode() or decodeSubset(). However, this can be called
136be08aceaab724b21136d7654fa86315850e9993creed     *  to override that, causing the codec to try to match the src depth instead
137be08aceaab724b21136d7654fa86315850e9993creed     *  (as shown below).
138be08aceaab724b21136d7654fa86315850e9993creed     *
139be08aceaab724b21136d7654fa86315850e9993creed     *      src_8Index  -> kIndex_8_SkColorType
140be08aceaab724b21136d7654fa86315850e9993creed     *      src_8Gray   -> kN32_SkColorType
141be08aceaab724b21136d7654fa86315850e9993creed     *      src_8bpc    -> kN32_SkColorType
142be08aceaab724b21136d7654fa86315850e9993creed     */
143be08aceaab724b21136d7654fa86315850e9993creed    void setPreserveSrcDepth(bool preserve) {
144be08aceaab724b21136d7654fa86315850e9993creed        fPreserveSrcDepth = preserve;
145be08aceaab724b21136d7654fa86315850e9993creed    }
146be08aceaab724b21136d7654fa86315850e9993creed
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::Allocator* getAllocator() const { return fAllocator; }
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*);
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // sample-size, if set to > 1, tells the decoder to return a smaller than
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // size is set to 3, then the returned bitmap will be 1/3 as wide and high,
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // and will contain 1/9 as many pixels as the original.
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Note: this is a hint, and the codec may choose to ignore this, or only
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // approximate the sample size.
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int getSampleSize() const { return fSampleSize; }
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void setSampleSize(int size);
15825e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Reset the sampleSize to its default of 1
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void resetSampleSize() { this->setSampleSize(1); }
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Decoding is synchronous, but for long decodes, a different thread can
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        call this method safely. This sets a state that the decoders will
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        periodically check, and if they see it changed to cancel, they will
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        cancel. This will result in decode() returning false. However, there is
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        no guarantee that the decoder will see the state change in time, so
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        it is possible that cancelDecode() will be called, but will be ignored
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        and decode() will return true (assuming no other problems were
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        encountered).
17125e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        This state is automatically reset at the beginning of decode().
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void cancelDecode() {
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // now the subclass must query shouldCancelDecode() to be informed
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // of the request
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fShouldCancelDecode = true;
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Passed to the decode method. If kDecodeBounds_Mode is passed, then
181bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed        only the bitmap's info need be set. If kDecodePixels_Mode
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        is passed, then the bitmap must have pixels or a pixelRef.
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    enum Mode {
185bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed        kDecodeBounds_Mode, //!< only return info in bitmap
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kDecodePixels_Mode  //!< return entire bitmap (including pixels)
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
18825e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
1892a1208017dd676f94a53bbb228197c3978dbdd8ascroggo    /** Result of a decode. If read as a boolean, a partial success is
1902a1208017dd676f94a53bbb228197c3978dbdd8ascroggo        considered a success (true).
1912a1208017dd676f94a53bbb228197c3978dbdd8ascroggo    */
1922a1208017dd676f94a53bbb228197c3978dbdd8ascroggo    enum Result {
1932a1208017dd676f94a53bbb228197c3978dbdd8ascroggo        kFailure        = 0,    //!< Image failed to decode. bitmap will be
1942a1208017dd676f94a53bbb228197c3978dbdd8ascroggo                                //   unchanged.
1952a1208017dd676f94a53bbb228197c3978dbdd8ascroggo        kPartialSuccess = 1,    //!< Part of the image decoded. The rest is
1962a1208017dd676f94a53bbb228197c3978dbdd8ascroggo                                //   filled in automatically
1972a1208017dd676f94a53bbb228197c3978dbdd8ascroggo        kSuccess        = 2     //!< The entire image was decoded, if Mode is
1982a1208017dd676f94a53bbb228197c3978dbdd8ascroggo                                //   kDecodePixels_Mode, or the bounds were
1992a1208017dd676f94a53bbb228197c3978dbdd8ascroggo                                //   decoded, in kDecodeBounds_Mode.
2002a1208017dd676f94a53bbb228197c3978dbdd8ascroggo    };
2012a1208017dd676f94a53bbb228197c3978dbdd8ascroggo
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Given a stream, decode it into the specified bitmap.
203bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed        If the decoder can decompress the image, it calls bitmap.setInfo(),
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        and then if the Mode is kDecodePixels_Mode, call allocPixelRef(),
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        which will allocated a pixelRef. To access the pixel memory, the codec
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        needs to call lockPixels/unlockPixels on the
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bitmap. It can then set the pixels with the decompressed image.
2082a1208017dd676f94a53bbb228197c3978dbdd8ascroggo    *   If the image cannot be decompressed, return kFailure. After the
209bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed    *   decoding, the function converts the decoded colortype in bitmap
21025e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com    *   to pref if possible. Whether a conversion is feasible is
21125e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com    *   tested by Bitmap::canCopyTo(pref).
21225e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
213bc69ce982f8374742ca910587485f0d741350c2dscroggo@google.com        If an SkBitmap::Allocator is installed via setAllocator, it will be
214bc69ce982f8374742ca910587485f0d741350c2dscroggo@google.com        used to allocate the pixel memory. A clever allocator can be used
215bc69ce982f8374742ca910587485f0d741350c2dscroggo@google.com        to allocate the memory from a cache, volatile memory, or even from
216bc69ce982f8374742ca910587485f0d741350c2dscroggo@google.com        an existing bitmap's memory.
217bc69ce982f8374742ca910587485f0d741350c2dscroggo@google.com
218cf98fa93116cf5efcc42d48c22fb4bd76896acdcscroggo        If an SkPngChunkReader is installed via setPeeker, it may be used to
219cf98fa93116cf5efcc42d48c22fb4bd76896acdcscroggo        peek into meta data during the decode.
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2212a1208017dd676f94a53bbb228197c3978dbdd8ascroggo    Result decode(SkStream*, SkBitmap* bitmap, SkColorType pref, Mode);
2222a1208017dd676f94a53bbb228197c3978dbdd8ascroggo    Result decode(SkStream* stream, SkBitmap* bitmap, Mode mode) {
223bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed        return this->decode(stream, bitmap, kUnknown_SkColorType, mode);
2243f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com    }
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Given a stream, this will try to find an appropriate decoder object.
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        If none is found, the method returns NULL.
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
229b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com    static SkImageDecoder* Factory(SkStreamRewindable*);
230a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Decode the image stored in the specified file, and store the result
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        in bitmap. Return true for success or false on failure.
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
234207a1c96ee789cc25a43e797b0729dd94dc747a5scroggo        @param pref Prefer this colortype.
23531d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com
236b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com        @param format On success, if format is non-null, it is set to the format
237b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com                      of the decoded file. On failure it is ignored.
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
239bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed    static bool DecodeFile(const char file[], SkBitmap* bitmap, SkColorType pref, Mode,
24031d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com                           Format* format = NULL);
241b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com    static bool DecodeFile(const char file[], SkBitmap* bitmap) {
242bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed        return DecodeFile(file, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
244bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Decode the image stored in the specified memory buffer, and store the
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        result in bitmap. Return true for success or false on failure.
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
248207a1c96ee789cc25a43e797b0729dd94dc747a5scroggo        @param pref Prefer this colortype.
24931d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com
25031d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com        @param format On success, if format is non-null, it is set to the format
251b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com                       of the decoded buffer. On failure it is ignored.
252b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com     */
253bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed    static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap, SkColorType pref,
254bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed                             Mode, Format* format = NULL);
255b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com    static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap){
256bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed        return DecodeMemory(buffer, size, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
258f8d7d2731318cdf510ab68e6b3f5ec68ab22c8e2scroggo@google.com
259b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com    /** Decode the image stored in the specified SkStreamRewindable, and store the result
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        in bitmap. Return true for success or false on failure.
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
262207a1c96ee789cc25a43e797b0729dd94dc747a5scroggo        @param pref Prefer this colortype.
26331d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com
264b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com        @param format On success, if format is non-null, it is set to the format
265b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com                      of the decoded stream. On failure it is ignored.
266b3ade9d1b0a63f8f0dc3bee5785e930c8e84311dreed@android.com     */
267bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed    static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap, SkColorType pref, Mode,
26831d1c64bd54dd2b216846a30da4cc2e96765ec5freed@android.com                             Format* format = NULL);
269b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com    static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap) {
270bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed        return DecodeStream(stream, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
27225e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // must be overridden in subclasses. This guy is called by decode(...)
2752a1208017dd676f94a53bbb228197c3978dbdd8ascroggo    virtual Result onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0;
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
277b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi    /** If planes or rowBytes is NULL, decodes the header and computes componentSizes
278b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi        for memory allocation.
279b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi        Otherwise, decodes the YUV planes into the provided image planes and
280b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi        updates componentSizes to the final image size.
281b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi        Returns whether the decoding was successful.
282b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi    */
283c87dd2ce965cd1bbc8a74abe0c141658a469d7f2djsollen    virtual bool onDecodeYUV8Planes(SkStream*, SkISize[3] /*componentSizes*/,
284c87dd2ce965cd1bbc8a74abe0c141658a469d7f2djsollen                                    void*[3] /*planes*/, size_t[3] /*rowBytes*/,
285c87dd2ce965cd1bbc8a74abe0c141658a469d7f2djsollen                                    SkYUVColorSpace*) {
286b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi        return false;
287b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi    }
288b227e37eae36ccf630c4baef00b1354d42b40fd1sugoi
289468142b2f50de055f00d5684515d962777da5131scroggo@google.com    /**
290468142b2f50de055f00d5684515d962777da5131scroggo@google.com     *  Copy all fields on this decoder to the other decoder. Used by subclasses
291468142b2f50de055f00d5684515d962777da5131scroggo@google.com     *  to decode a subimage using a different decoder, but with the same settings.
292468142b2f50de055f00d5684515d962777da5131scroggo@google.com     */
293468142b2f50de055f00d5684515d962777da5131scroggo@google.com    void copyFieldsToOther(SkImageDecoder* other);
294a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Can be queried from within onDecode, to see if the user (possibly in
2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        a different thread) has requested the decode to cancel. If this returns
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        true, your onDecode() should stop and return false.
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Each subclass needs to decide how often it can query this, to balance
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        responsiveness with performance.
30025e9834c03a050afbf339f457b8c401aecb26c0bweita@google.com
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Calling this outside of onDecode() may return undefined values.
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool shouldCancelDecode() const { return fShouldCancelDecode; }
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
30725e9834c03a050afbf339f457b8c401aecb26c0bweita@google.comprotected:
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkImageDecoder();
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
310bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed    /**
311bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed     *  Return the default preference being used by the current or latest call to decode.
312bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed     */
313bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed    SkColorType getDefaultPref() { return fDefaultPref; }
3142766c00fc0b6a07d46e5f74cdad45da2ef625237mtklein
315bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed    /*  Helper for subclasses. Call this to allocate the pixel memory given the bitmap's info.
316bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed        Returns true on success. This method handles checking for an optional Allocator.
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool allocPixelRef(SkBitmap*, SkColorTable*) const;
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
320f698c8262df397a7015662e91b1a727e1134c418scroggo@google.com    /**
321f698c8262df397a7015662e91b1a727e1134c418scroggo@google.com     *  The raw data of the src image.
322f698c8262df397a7015662e91b1a727e1134c418scroggo@google.com     */
3233f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com    enum SrcDepth {
324f698c8262df397a7015662e91b1a727e1134c418scroggo@google.com        // Color-indexed.
3253f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com        kIndex_SrcDepth,
326f698c8262df397a7015662e91b1a727e1134c418scroggo@google.com        // Grayscale in 8 bits.
327f698c8262df397a7015662e91b1a727e1134c418scroggo@google.com        k8BitGray_SrcDepth,
328f698c8262df397a7015662e91b1a727e1134c418scroggo@google.com        // 8 bits per component. Used for 24 bit if there is no alpha.
329f698c8262df397a7015662e91b1a727e1134c418scroggo@google.com        k32Bit_SrcDepth,
3303f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com    };
3316c22573edb234ad14df947278cfed010669a39a7reed    /** The subclass, inside onDecode(), calls this to determine the colorType of
3323f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com        the returned bitmap. SrcDepth and hasAlpha reflect the raw data of the
3333f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com        src image. This routine returns the caller's preference given
3346c22573edb234ad14df947278cfed010669a39a7reed        srcDepth and hasAlpha, or kUnknown_SkColorType if there is no preference.
3353f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com     */
3366c22573edb234ad14df947278cfed010669a39a7reed    SkColorType getPrefColorType(SrcDepth, bool hasAlpha) const;
3373f1f06a26bdb2022a5c72f93ae623a57b6659464reed@android.com
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
339cf98fa93116cf5efcc42d48c22fb4bd76896acdcscroggo    SkPngChunkReader*       fPeeker;
3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::Allocator*    fAllocator;
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int                     fSampleSize;
342bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed    SkColorType             fDefaultPref;   // use if fUsePrefTable is false
343be08aceaab724b21136d7654fa86315850e9993creed    bool                    fPreserveSrcDepth;
344c3b3266b7db2f1a41d41ecac010c766b7ad8eebcreed    bool                    fDitherImage;
3458d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com    bool                    fSkipWritingZeroes;
3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    mutable bool            fShouldCancelDecode;
347a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org    bool                    fPreferQualityOverSpeed;
3482bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com    bool                    fRequireUnpremultipliedColors;
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
351a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com/** Calling newDecoder with a stream returns a new matching imagedecoder
352a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    instance, or NULL if none can be found. The caller must manage its ownership
353a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    of the stream as usual, calling unref() when it is done, as the returned
354a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    decoder may have called ref() (and if so, the decoder is responsible for
355a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    balancing its ownership when it is destroyed).
356a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com */
357a14ea0e930c82daa2364ece4bd0b06256272302areed@android.comclass SkImageDecoderFactory : public SkRefCnt {
358a14ea0e930c82daa2364ece4bd0b06256272302areed@android.compublic:
3592766c00fc0b6a07d46e5f74cdad45da2ef625237mtklein
36015e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com
361b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com    virtual SkImageDecoder* newDecoder(SkStreamRewindable*) = 0;
36215e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com
36315e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.comprivate:
36415e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com    typedef SkRefCnt INHERITED;
365a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com};
366a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com
367a14ea0e930c82daa2364ece4bd0b06256272302areed@android.comclass SkDefaultImageDecoderFactory : SkImageDecoderFactory {
368a14ea0e930c82daa2364ece4bd0b06256272302areed@android.compublic:
369a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    // calls SkImageDecoder::Factory(stream)
370b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com    virtual SkImageDecoder* newDecoder(SkStreamRewindable* stream) {
371a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com        return SkImageDecoder::Factory(stream);
372a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    }
373a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com};
374a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com
375ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com// This macro declares a global (i.e., non-class owned) creation entry point
376ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com// for each decoder (e.g., CreateJPEGImageDecoder)
377ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com#define DECLARE_DECODER_CREATOR(codec)          \
378ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com    SkImageDecoder *Create ## codec ();
379ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com
380ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com// This macro defines the global creation entry point for each decoder. Each
381ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com// decoder implementation that registers with the decoder factory must call it.
382385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary#define DEFINE_DECODER_CREATOR(codec) \
383385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    SkImageDecoder* Create##codec() { return new Sk##codec; }
384ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com
385ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com// All the decoders known by Skia. Note that, depending on the compiler settings,
386ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.com// not all of these will be available
387ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.comDECLARE_DECODER_CREATOR(BMPImageDecoder);
388ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.comDECLARE_DECODER_CREATOR(GIFImageDecoder);
389ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.comDECLARE_DECODER_CREATOR(ICOImageDecoder);
390ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.comDECLARE_DECODER_CREATOR(JPEGImageDecoder);
391ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.comDECLARE_DECODER_CREATOR(PNGImageDecoder);
392ec51cb863409e238b40c5beef458669d9a824481robertphillips@google.comDECLARE_DECODER_CREATOR(WBMPImageDecoder);
393a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgDECLARE_DECODER_CREATOR(WEBPImageDecoder);
3948cf81e0f4fa2a8054ac4cea1e7490028809cb893robertphillips@google.comDECLARE_DECODER_CREATOR(PKMImageDecoder);
39599ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevskiDECLARE_DECODER_CREATOR(KTXImageDecoder);
39695b1b3d82d227141647777d83324aa570b530096krajcevskiDECLARE_DECODER_CREATOR(ASTCImageDecoder);
397bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com
398bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com// Typedefs to make registering decoder and formatter callbacks easier.
399bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com// These have to be defined outside SkImageDecoder. :(
400b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comtypedef SkTRegistry<SkImageDecoder*(*)(SkStreamRewindable*)>        SkImageDecoder_DecodeReg;
401b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comtypedef SkTRegistry<SkImageDecoder::Format(*)(SkStreamRewindable*)> SkImageDecoder_FormatReg;
402bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.com
4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
404