2 * Copyright 2015 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef SkCodec_DEFINED
9 #define SkCodec_DEFINED
11 #include "SkEncodedFormat.h"
12 #include "SkImageGenerator.h"
13 #include "SkImageInfo.h"
14 #include "SkScanlineDecoder.h"
17 #include "SkTemplates.h"
23 * Abstraction layer directly on top of an image codec.
25 class SkCodec : public SkImageGenerator {
28 * If this stream represents an encoded image that we know how to decode,
29 * return an SkCodec that can decode it. Otherwise return NULL.
31 * If NULL is returned, the stream is deleted immediately. Otherwise, the
32 * SkCodec takes ownership of it, and will delete it when done with it.
34 static SkCodec* NewFromStream(SkStream*);
37 * If this data represents an encoded image that we know how to decode,
38 * return an SkCodec that can decode it. Otherwise return NULL.
40 * Will take a ref if it returns a codec, else will not affect the data.
42 static SkCodec* NewFromData(SkData*);
45 * Return a size that approximately supports the desired scale factor.
46 * The codec may not be able to scale efficiently to the exact scale
47 * factor requested, so return a size that approximates that scale.
49 * FIXME: Move to SkImageGenerator?
51 SkISize getScaledDimensions(float desiredScale) const {
52 return this->onGetScaledDimensions(desiredScale);
56 * Format of the encoded data.
58 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
61 * Return an object which can be used to decode individual scanlines.
63 * This object is owned by the SkCodec, which will handle its lifetime. The
64 * returned object is only valid until the SkCodec is deleted or the next
65 * call to getScanlineDecoder, whichever comes first.
67 * Calling a second time will rewind and replace the existing one with a
68 * new one. If the stream cannot be rewound, this will delete the existing
69 * one and return NULL.
71 * @param dstInfo Info of the destination. If the dimensions do not match
72 * those of getInfo, this implies a scale.
73 * @return New SkScanlineDecoder, or NULL on failure.
75 * NOTE: If any rows were previously decoded, this requires rewinding the
78 * NOTE: The scanline decoder is owned by the SkCodec and will delete it
79 * when the SkCodec is deleted.
81 SkScanlineDecoder* getScanlineDecoder(const SkImageInfo& dstInfo);
84 * Some images may initially report that they have alpha due to the format
85 * of the encoded data, but then never use any colors which have alpha
86 * less than 100%. This function can be called *after* decoding to
87 * determine if such an image truly had alpha. Calling it before decoding
89 * FIXME: see skbug.com/3582.
91 bool reallyHasAlpha() const {
92 return this->onReallyHasAlpha();
96 SkCodec(const SkImageInfo&, SkStream*);
99 * The SkAlphaType is a conservative answer. i.e. it is possible that it
100 * initially returns a non-opaque answer, but completing the decode
101 * reveals that the image is actually opaque.
103 #ifdef SK_SUPPORT_LEGACY_BOOL_ONGETINFO
104 bool onGetInfo(SkImageInfo* info) override {
110 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
111 // By default, scaling is not supported.
112 return fInfo.dimensions();
115 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
118 * Override if your codec supports scanline decoding.
120 * No need to call rewindIfNeeded(), which will have already been called
123 * @param dstInfo Info of the destination. If the dimensions do not match
124 * those of getInfo, this implies a scale.
125 * @return New SkScanlineDecoder on success, NULL otherwise. The SkCodec
126 * will take ownership of the returned scanline decoder.
128 virtual SkScanlineDecoder* onGetScanlineDecoder(const SkImageInfo& dstInfo) {
132 virtual bool onReallyHasAlpha() const { return false; }
135 * If the stream was previously read, attempt to rewind.
138 * - if the stream needed to be rewound, and the rewind
140 * - if the stream did not need to be rewound.
142 * - if the stream needed to be rewound, and rewind failed.
143 * Subclasses MUST call this function before reading the stream (e.g. in
144 * onGetPixels). If it returns false, onGetPixels should return
147 bool SK_WARN_UNUSED_RESULT rewindIfNeeded();
151 * Get method for the input stream
155 return fStream.get();
159 const SkImageInfo fInfo;
160 SkAutoTDelete<SkStream> fStream;
162 SkAutoTDelete<SkScanlineDecoder> fScanlineDecoder;
164 typedef SkImageGenerator INHERITED;
166 #endif // SkCodec_DEFINED