blob: a8ec1c651829adacdcba6239a72eb48b3b2d07be [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkImageDecoder_DEFINED
11#define SkImageDecoder_DEFINED
12
13#include "SkBitmap.h"
14#include "SkRefCnt.h"
15
16class SkStream;
17
18/** \class SkImageDecoder
19
20 Base class for decoding compressed images into a SkBitmap
21*/
22class SkImageDecoder {
23public:
24 virtual ~SkImageDecoder();
weita@google.com25e98342009-05-11 16:06:22 +000025
reed@android.com8a1c16f2008-12-17 15:59:43 +000026 enum Format {
27 kUnknown_Format,
28 kBMP_Format,
29 kGIF_Format,
30 kICO_Format,
31 kJPEG_Format,
32 kPNG_Format,
33 kWBMP_Format,
weita@google.com25e98342009-05-11 16:06:22 +000034
reed@android.com8a1c16f2008-12-17 15:59:43 +000035 kLastKnownFormat = kWBMP_Format
36 };
weita@google.com25e98342009-05-11 16:06:22 +000037
reed@android.com8a1c16f2008-12-17 15:59:43 +000038 /** Return the compressed data's format (see Format enum)
39 */
40 virtual Format getFormat() const;
41
42 /** Returns true if the decoder should try to dither the resulting image.
43 The default setting is true.
44 */
45 bool getDitherImage() const { return fDitherImage; }
weita@google.com25e98342009-05-11 16:06:22 +000046
reed@android.com8a1c16f2008-12-17 15:59:43 +000047 /** Set to true if the the decoder should try to dither the resulting image.
48 The default setting is true.
49 */
50 void setDitherImage(bool dither) { fDitherImage = dither; }
51
52 /** \class Peeker
weita@google.com25e98342009-05-11 16:06:22 +000053
reed@android.com8a1c16f2008-12-17 15:59:43 +000054 Base class for optional callbacks to retrieve meta/chunk data out of
55 an image as it is being decoded.
56 */
57 class Peeker : public SkRefCnt {
58 public:
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000059 SK_DECLARE_INST_COUNT(Peeker)
60
reed@android.com8a1c16f2008-12-17 15:59:43 +000061 /** Return true to continue decoding, or false to indicate an error, which
62 will cause the decoder to not return the image.
63 */
64 virtual bool peek(const char tag[], const void* data, size_t length) = 0;
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000065 private:
66 typedef SkRefCnt INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +000067 };
68
69 Peeker* getPeeker() const { return fPeeker; }
70 Peeker* setPeeker(Peeker*);
weita@google.com25e98342009-05-11 16:06:22 +000071
reed@android.com8a1c16f2008-12-17 15:59:43 +000072 /** \class Peeker
weita@google.com25e98342009-05-11 16:06:22 +000073
reed@android.com8a1c16f2008-12-17 15:59:43 +000074 Base class for optional callbacks to retrieve meta/chunk data out of
75 an image as it is being decoded.
76 */
77 class Chooser : public SkRefCnt {
78 public:
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000079 SK_DECLARE_INST_COUNT(Chooser)
80
reed@android.com8a1c16f2008-12-17 15:59:43 +000081 virtual void begin(int count) {}
82 virtual void inspect(int index, SkBitmap::Config config, int width, int height) {}
83 /** Return the index of the subimage you want, or -1 to choose none of them.
84 */
85 virtual int choose() = 0;
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000086
87 private:
88 typedef SkRefCnt INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +000089 };
90
91 Chooser* getChooser() const { return fChooser; }
92 Chooser* setChooser(Chooser*);
93
reed@android.com3f1f06a2010-03-03 21:04:12 +000094 /** This optional table describes the caller's preferred config based on
95 information about the src data. For this table, the src attributes are
96 described in terms of depth (index (8), 16, 32/24) and if there is
97 per-pixel alpha. These inputs combine to create an index into the
98 pref[] table, which contains the caller's preferred config for that
99 input, or kNo_Config if there is no preference.
100
101 To specify no preferrence, call setPrefConfigTable(NULL), which is
102 the default.
103
104 Note, it is still at the discretion of the codec as to what output
105 config is actually returned, as it may not be able to support the
106 caller's preference.
107
108 Here is how the index into the table is computed from the src:
109 depth [8, 16, 32/24] -> 0, 2, 4
110 alpha [no, yes] -> 0, 1
111 The two index values are OR'd together.
112 src: 8-index, no-alpha -> 0
113 src: 8-index, yes-alpha -> 1
114 src: 16bit, no-alpha -> 2 // e.g. 565
115 src: 16bit, yes-alpha -> 3 // e.g. 1555
116 src: 32/24, no-alpha -> 4
117 src: 32/24, yes-alpha -> 5
118 */
119 void setPrefConfigTable(const SkBitmap::Config pref[6]);
120
reed@android.com8a1c16f2008-12-17 15:59:43 +0000121 SkBitmap::Allocator* getAllocator() const { return fAllocator; }
122 SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*);
123
124 // sample-size, if set to > 1, tells the decoder to return a smaller than
125 // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample
126 // size is set to 3, then the returned bitmap will be 1/3 as wide and high,
127 // and will contain 1/9 as many pixels as the original.
128 // Note: this is a hint, and the codec may choose to ignore this, or only
129 // approximate the sample size.
130 int getSampleSize() const { return fSampleSize; }
131 void setSampleSize(int size);
weita@google.com25e98342009-05-11 16:06:22 +0000132
reed@android.com8a1c16f2008-12-17 15:59:43 +0000133 /** Reset the sampleSize to its default of 1
134 */
135 void resetSampleSize() { this->setSampleSize(1); }
136
137 /** Decoding is synchronous, but for long decodes, a different thread can
138 call this method safely. This sets a state that the decoders will
139 periodically check, and if they see it changed to cancel, they will
140 cancel. This will result in decode() returning false. However, there is
141 no guarantee that the decoder will see the state change in time, so
142 it is possible that cancelDecode() will be called, but will be ignored
143 and decode() will return true (assuming no other problems were
144 encountered).
weita@google.com25e98342009-05-11 16:06:22 +0000145
reed@android.com8a1c16f2008-12-17 15:59:43 +0000146 This state is automatically reset at the beginning of decode().
147 */
148 void cancelDecode() {
149 // now the subclass must query shouldCancelDecode() to be informed
150 // of the request
151 fShouldCancelDecode = true;
152 }
153
154 /** Passed to the decode method. If kDecodeBounds_Mode is passed, then
155 only the bitmap's width/height/config need be set. If kDecodePixels_Mode
156 is passed, then the bitmap must have pixels or a pixelRef.
157 */
158 enum Mode {
159 kDecodeBounds_Mode, //!< only return width/height/config in bitmap
160 kDecodePixels_Mode //!< return entire bitmap (including pixels)
161 };
weita@google.com25e98342009-05-11 16:06:22 +0000162
reed@android.com8a1c16f2008-12-17 15:59:43 +0000163 /** Given a stream, decode it into the specified bitmap.
164 If the decoder can decompress the image, it calls bitmap.setConfig(),
165 and then if the Mode is kDecodePixels_Mode, call allocPixelRef(),
166 which will allocated a pixelRef. To access the pixel memory, the codec
167 needs to call lockPixels/unlockPixels on the
168 bitmap. It can then set the pixels with the decompressed image.
weita@google.com25e98342009-05-11 16:06:22 +0000169 * If the image cannot be decompressed, return false. After the
170 * decoding, the function converts the decoded config in bitmap
171 * to pref if possible. Whether a conversion is feasible is
172 * tested by Bitmap::canCopyTo(pref).
173
174 note: document use of Allocator, Peeker and Chooser
reed@android.com8a1c16f2008-12-17 15:59:43 +0000175 */
176 bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode);
reed@android.com3f1f06a2010-03-03 21:04:12 +0000177 bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) {
178 return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode);
179 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000180
181 /** Given a stream, this will try to find an appropriate decoder object.
182 If none is found, the method returns NULL.
183 */
184 static SkImageDecoder* Factory(SkStream*);
reed@android.coma14ea0e2009-03-17 17:59:53 +0000185
reed@android.com8a1c16f2008-12-17 15:59:43 +0000186 /** Decode the image stored in the specified file, and store the result
187 in bitmap. Return true for success or false on failure.
188
189 If pref is kNo_Config, then the decoder is free to choose the most natural
190 config given the image data. If pref something other than kNo_Config,
191 the decoder will attempt to decode the image into that format, unless
192 there is a conflict (e.g. the image has per-pixel alpha and the bitmap's
193 config does not support that), in which case the decoder will choose a
194 closest match configuration.
reed@android.com31d1c642009-06-15 18:45:19 +0000195
reed@android.comb3ade9d2009-06-15 13:04:45 +0000196 @param format On success, if format is non-null, it is set to the format
197 of the decoded file. On failure it is ignored.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000198 */
199 static bool DecodeFile(const char file[], SkBitmap* bitmap,
reed@android.comb3ade9d2009-06-15 13:04:45 +0000200 SkBitmap::Config prefConfig, Mode,
reed@android.com31d1c642009-06-15 18:45:19 +0000201 Format* format = NULL);
reed@android.comb3ade9d2009-06-15 13:04:45 +0000202 static bool DecodeFile(const char file[], SkBitmap* bitmap) {
203 return DecodeFile(file, bitmap, SkBitmap::kNo_Config,
204 kDecodePixels_Mode, NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205 }
206 /** Decode the image stored in the specified memory buffer, and store the
207 result in bitmap. Return true for success or false on failure.
208
209 If pref is kNo_Config, then the decoder is free to choose the most natural
210 config given the image data. If pref something other than kNo_Config,
211 the decoder will attempt to decode the image into that format, unless
212 there is a conflict (e.g. the image has per-pixel alpha and the bitmap's
213 config does not support that), in which case the decoder will choose a
214 closest match configuration.
reed@android.com31d1c642009-06-15 18:45:19 +0000215
216 @param format On success, if format is non-null, it is set to the format
reed@android.comb3ade9d2009-06-15 13:04:45 +0000217 of the decoded buffer. On failure it is ignored.
218 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000219 static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap,
reed@android.comb3ade9d2009-06-15 13:04:45 +0000220 SkBitmap::Config prefConfig, Mode,
reed@android.com31d1c642009-06-15 18:45:19 +0000221 Format* format = NULL);
reed@android.comb3ade9d2009-06-15 13:04:45 +0000222 static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap){
reed@android.com8a1c16f2008-12-17 15:59:43 +0000223 return DecodeMemory(buffer, size, bitmap, SkBitmap::kNo_Config,
reed@android.comb3ade9d2009-06-15 13:04:45 +0000224 kDecodePixels_Mode, NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000225 }
226 /** Decode the image stored in the specified SkStream, and store the result
227 in bitmap. Return true for success or false on failure.
228
229 If pref is kNo_Config, then the decoder is free to choose the most
230 natural config given the image data. If pref something other than
231 kNo_Config, the decoder will attempt to decode the image into that
232 format, unless there is a conflict (e.g. the image has per-pixel alpha
233 and the bitmap's config does not support that), in which case the
234 decoder will choose a closest match configuration.
reed@android.com31d1c642009-06-15 18:45:19 +0000235
reed@android.comb3ade9d2009-06-15 13:04:45 +0000236 @param format On success, if format is non-null, it is set to the format
237 of the decoded stream. On failure it is ignored.
238 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000239 static bool DecodeStream(SkStream* stream, SkBitmap* bitmap,
reed@android.comb3ade9d2009-06-15 13:04:45 +0000240 SkBitmap::Config prefConfig, Mode,
reed@android.com31d1c642009-06-15 18:45:19 +0000241 Format* format = NULL);
reed@android.comb3ade9d2009-06-15 13:04:45 +0000242 static bool DecodeStream(SkStream* stream, SkBitmap* bitmap) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000243 return DecodeStream(stream, bitmap, SkBitmap::kNo_Config,
reed@android.comb3ade9d2009-06-15 13:04:45 +0000244 kDecodePixels_Mode, NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000245 }
weita@google.com25e98342009-05-11 16:06:22 +0000246
reed@android.com8a1c16f2008-12-17 15:59:43 +0000247 /** Return the default config for the running device.
248 Currently this used as a suggestion to image decoders that need to guess
249 what config they should decode into.
250 Default is kNo_Config, but this can be changed with SetDeviceConfig()
251 */
252 static SkBitmap::Config GetDeviceConfig();
253 /** Set the default config for the running device.
254 Currently this used as a suggestion to image decoders that need to guess
255 what config they should decode into.
256 Default is kNo_Config.
257 This can be queried with GetDeviceConfig()
258 */
259 static void SetDeviceConfig(SkBitmap::Config);
260
261 /** @cond UNIT_TEST */
262 SkDEBUGCODE(static void UnitTest();)
263 /** @endcond */
264
265protected:
266 // must be overridden in subclasses. This guy is called by decode(...)
reed@android.com3f1f06a2010-03-03 21:04:12 +0000267 virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000268
269 /** Can be queried from within onDecode, to see if the user (possibly in
270 a different thread) has requested the decode to cancel. If this returns
271 true, your onDecode() should stop and return false.
272 Each subclass needs to decide how often it can query this, to balance
273 responsiveness with performance.
weita@google.com25e98342009-05-11 16:06:22 +0000274
reed@android.com8a1c16f2008-12-17 15:59:43 +0000275 Calling this outside of onDecode() may return undefined values.
276 */
277
278public:
279 bool shouldCancelDecode() const { return fShouldCancelDecode; }
280
weita@google.com25e98342009-05-11 16:06:22 +0000281protected:
reed@android.com8a1c16f2008-12-17 15:59:43 +0000282 SkImageDecoder();
283
284 // helper function for decoders to handle the (common) case where there is only
285 // once choice available in the image file.
286 bool chooseFromOneChoice(SkBitmap::Config config, int width, int height) const;
287
288 /* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's
289 width/height/rowbytes/config. Returns true on success. This method handles checking
290 for an optional Allocator.
291 */
292 bool allocPixelRef(SkBitmap*, SkColorTable*) const;
293
reed@android.com3f1f06a2010-03-03 21:04:12 +0000294 enum SrcDepth {
295 kIndex_SrcDepth,
296 k16Bit_SrcDepth,
297 k32Bit_SrcDepth
298 };
299 /** The subclass, inside onDecode(), calls this to determine the config of
300 the returned bitmap. SrcDepth and hasAlpha reflect the raw data of the
301 src image. This routine returns the caller's preference given
302 srcDepth and hasAlpha, or kNo_Config if there is no preference.
303
304 Note: this also takes into account GetDeviceConfig(), so the subclass
305 need not call that.
306 */
307 SkBitmap::Config getPrefConfig(SrcDepth, bool hasAlpha) const;
308
reed@android.com8a1c16f2008-12-17 15:59:43 +0000309private:
310 Peeker* fPeeker;
311 Chooser* fChooser;
312 SkBitmap::Allocator* fAllocator;
313 int fSampleSize;
reed@android.com3f1f06a2010-03-03 21:04:12 +0000314 SkBitmap::Config fDefaultPref; // use if fUsePrefTable is false
315 SkBitmap::Config fPrefTable[6]; // use if fUsePrefTable is true
reed@android.com8a1c16f2008-12-17 15:59:43 +0000316 bool fDitherImage;
reed@android.com3f1f06a2010-03-03 21:04:12 +0000317 bool fUsePrefTable;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000318 mutable bool fShouldCancelDecode;
319
320 // illegal
321 SkImageDecoder(const SkImageDecoder&);
322 SkImageDecoder& operator=(const SkImageDecoder&);
323};
324
reed@android.coma14ea0e2009-03-17 17:59:53 +0000325/** Calling newDecoder with a stream returns a new matching imagedecoder
326 instance, or NULL if none can be found. The caller must manage its ownership
327 of the stream as usual, calling unref() when it is done, as the returned
328 decoder may have called ref() (and if so, the decoder is responsible for
329 balancing its ownership when it is destroyed).
330 */
331class SkImageDecoderFactory : public SkRefCnt {
332public:
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +0000333 SK_DECLARE_INST_COUNT(SkImageDecoderFactory)
334
reed@android.coma14ea0e2009-03-17 17:59:53 +0000335 virtual SkImageDecoder* newDecoder(SkStream*) = 0;
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +0000336
337private:
338 typedef SkRefCnt INHERITED;
reed@android.coma14ea0e2009-03-17 17:59:53 +0000339};
340
341class SkDefaultImageDecoderFactory : SkImageDecoderFactory {
342public:
343 // calls SkImageDecoder::Factory(stream)
344 virtual SkImageDecoder* newDecoder(SkStream* stream) {
345 return SkImageDecoder::Factory(stream);
346 }
347};
348
robertphillips@google.comec51cb82012-03-23 18:13:47 +0000349// This macro declares a global (i.e., non-class owned) creation entry point
350// for each decoder (e.g., CreateJPEGImageDecoder)
351#define DECLARE_DECODER_CREATOR(codec) \
352 SkImageDecoder *Create ## codec ();
353
354// This macro defines the global creation entry point for each decoder. Each
355// decoder implementation that registers with the decoder factory must call it.
356#define DEFINE_DECODER_CREATOR(codec) \
357 SkImageDecoder *Create ## codec () { \
358 return SkNEW( Sk ## codec ); \
359 }
360
361// All the decoders known by Skia. Note that, depending on the compiler settings,
362// not all of these will be available
363DECLARE_DECODER_CREATOR(BMPImageDecoder);
364DECLARE_DECODER_CREATOR(GIFImageDecoder);
365DECLARE_DECODER_CREATOR(ICOImageDecoder);
366DECLARE_DECODER_CREATOR(JPEGImageDecoder);
367DECLARE_DECODER_CREATOR(PNGImageDecoder);
368DECLARE_DECODER_CREATOR(WBMPImageDecoder);
reed@android.coma14ea0e2009-03-17 17:59:53 +0000369
reed@android.com8a1c16f2008-12-17 15:59:43 +0000370#endif