1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SkImageDecoder_DEFINED 18 #define SkImageDecoder_DEFINED 19 20 #include "SkBitmap.h" 21 #include "SkRefCnt.h" 22 23 class SkStream; 24 25 /** \class SkImageDecoder 26 27 Base class for decoding compressed images into a SkBitmap 28 */ 29 class SkImageDecoder { 30 public: 31 virtual ~SkImageDecoder(); 32 33 enum Format { 34 kUnknown_Format, 35 kBMP_Format, 36 kGIF_Format, 37 kICO_Format, 38 kJPEG_Format, 39 kPNG_Format, 40 kWBMP_Format, 41 42 kLastKnownFormat = kWBMP_Format 43 }; 44 45 /** Return the compressed data's format (see Format enum) 46 */ 47 virtual Format getFormat() const; 48 49 /** Returns true if the decoder should try to dither the resulting image. 50 The default setting is true. 51 */ getDitherImage()52 bool getDitherImage() const { return fDitherImage; } 53 54 /** Set to true if the the decoder should try to dither the resulting image. 55 The default setting is true. 56 */ setDitherImage(bool dither)57 void setDitherImage(bool dither) { fDitherImage = dither; } 58 59 /** \class Peeker 60 61 Base class for optional callbacks to retrieve meta/chunk data out of 62 an image as it is being decoded. 63 */ 64 class Peeker : public SkRefCnt { 65 public: 66 /** Return true to continue decoding, or false to indicate an error, which 67 will cause the decoder to not return the image. 68 */ 69 virtual bool peek(const char tag[], const void* data, size_t length) = 0; 70 }; 71 getPeeker()72 Peeker* getPeeker() const { return fPeeker; } 73 Peeker* setPeeker(Peeker*); 74 75 /** \class Peeker 76 77 Base class for optional callbacks to retrieve meta/chunk data out of 78 an image as it is being decoded. 79 */ 80 class Chooser : public SkRefCnt { 81 public: begin(int count)82 virtual void begin(int count) {} inspect(int index,SkBitmap::Config config,int width,int height)83 virtual void inspect(int index, SkBitmap::Config config, int width, int height) {} 84 /** Return the index of the subimage you want, or -1 to choose none of them. 85 */ 86 virtual int choose() = 0; 87 }; 88 getChooser()89 Chooser* getChooser() const { return fChooser; } 90 Chooser* setChooser(Chooser*); 91 getAllocator()92 SkBitmap::Allocator* getAllocator() const { return fAllocator; } 93 SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*); 94 95 // sample-size, if set to > 1, tells the decoder to return a smaller than 96 // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample 97 // size is set to 3, then the returned bitmap will be 1/3 as wide and high, 98 // and will contain 1/9 as many pixels as the original. 99 // Note: this is a hint, and the codec may choose to ignore this, or only 100 // approximate the sample size. getSampleSize()101 int getSampleSize() const { return fSampleSize; } 102 void setSampleSize(int size); 103 104 /** Reset the sampleSize to its default of 1 105 */ resetSampleSize()106 void resetSampleSize() { this->setSampleSize(1); } 107 108 /** Decoding is synchronous, but for long decodes, a different thread can 109 call this method safely. This sets a state that the decoders will 110 periodically check, and if they see it changed to cancel, they will 111 cancel. This will result in decode() returning false. However, there is 112 no guarantee that the decoder will see the state change in time, so 113 it is possible that cancelDecode() will be called, but will be ignored 114 and decode() will return true (assuming no other problems were 115 encountered). 116 117 This state is automatically reset at the beginning of decode(). 118 */ cancelDecode()119 void cancelDecode() { 120 // now the subclass must query shouldCancelDecode() to be informed 121 // of the request 122 fShouldCancelDecode = true; 123 } 124 125 /** Passed to the decode method. If kDecodeBounds_Mode is passed, then 126 only the bitmap's width/height/config need be set. If kDecodePixels_Mode 127 is passed, then the bitmap must have pixels or a pixelRef. 128 */ 129 enum Mode { 130 kDecodeBounds_Mode, //!< only return width/height/config in bitmap 131 kDecodePixels_Mode //!< return entire bitmap (including pixels) 132 }; 133 134 /** Given a stream, decode it into the specified bitmap. 135 If the decoder can decompress the image, it calls bitmap.setConfig(), 136 and then if the Mode is kDecodePixels_Mode, call allocPixelRef(), 137 which will allocated a pixelRef. To access the pixel memory, the codec 138 needs to call lockPixels/unlockPixels on the 139 bitmap. It can then set the pixels with the decompressed image. 140 * If the image cannot be decompressed, return false. After the 141 * decoding, the function converts the decoded config in bitmap 142 * to pref if possible. Whether a conversion is feasible is 143 * tested by Bitmap::canCopyTo(pref). 144 145 note: document use of Allocator, Peeker and Chooser 146 */ 147 bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode); 148 149 /** Given a stream, this will try to find an appropriate decoder object. 150 If none is found, the method returns NULL. 151 */ 152 static SkImageDecoder* Factory(SkStream*); 153 154 /** Decode the image stored in the specified file, and store the result 155 in bitmap. Return true for success or false on failure. 156 157 If pref is kNo_Config, then the decoder is free to choose the most natural 158 config given the image data. If pref something other than kNo_Config, 159 the decoder will attempt to decode the image into that format, unless 160 there is a conflict (e.g. the image has per-pixel alpha and the bitmap's 161 config does not support that), in which case the decoder will choose a 162 closest match configuration. 163 164 @param format On success, if format is non-null, it is set to the format 165 of the decoded file. On failure it is ignored. 166 */ 167 static bool DecodeFile(const char file[], SkBitmap* bitmap, 168 SkBitmap::Config prefConfig, Mode, 169 Format* format = NULL); DecodeFile(const char file[],SkBitmap * bitmap)170 static bool DecodeFile(const char file[], SkBitmap* bitmap) { 171 return DecodeFile(file, bitmap, SkBitmap::kNo_Config, 172 kDecodePixels_Mode, NULL); 173 } 174 /** Decode the image stored in the specified memory buffer, and store the 175 result in bitmap. Return true for success or false on failure. 176 177 If pref is kNo_Config, then the decoder is free to choose the most natural 178 config given the image data. If pref something other than kNo_Config, 179 the decoder will attempt to decode the image into that format, unless 180 there is a conflict (e.g. the image has per-pixel alpha and the bitmap's 181 config does not support that), in which case the decoder will choose a 182 closest match configuration. 183 184 @param format On success, if format is non-null, it is set to the format 185 of the decoded buffer. On failure it is ignored. 186 */ 187 static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap, 188 SkBitmap::Config prefConfig, Mode, 189 Format* format = NULL); DecodeMemory(const void * buffer,size_t size,SkBitmap * bitmap)190 static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap){ 191 return DecodeMemory(buffer, size, bitmap, SkBitmap::kNo_Config, 192 kDecodePixels_Mode, NULL); 193 } 194 /** Decode the image stored in the specified SkStream, and store the result 195 in bitmap. Return true for success or false on failure. 196 197 If pref is kNo_Config, then the decoder is free to choose the most 198 natural config given the image data. If pref something other than 199 kNo_Config, the decoder will attempt to decode the image into that 200 format, unless there is a conflict (e.g. the image has per-pixel alpha 201 and the bitmap's config does not support that), in which case the 202 decoder will choose a closest match configuration. 203 204 @param format On success, if format is non-null, it is set to the format 205 of the decoded stream. On failure it is ignored. 206 */ 207 static bool DecodeStream(SkStream* stream, SkBitmap* bitmap, 208 SkBitmap::Config prefConfig, Mode, 209 Format* format = NULL); DecodeStream(SkStream * stream,SkBitmap * bitmap)210 static bool DecodeStream(SkStream* stream, SkBitmap* bitmap) { 211 return DecodeStream(stream, bitmap, SkBitmap::kNo_Config, 212 kDecodePixels_Mode, NULL); 213 } 214 215 /** Return the default config for the running device. 216 Currently this used as a suggestion to image decoders that need to guess 217 what config they should decode into. 218 Default is kNo_Config, but this can be changed with SetDeviceConfig() 219 */ 220 static SkBitmap::Config GetDeviceConfig(); 221 /** Set the default config for the running device. 222 Currently this used as a suggestion to image decoders that need to guess 223 what config they should decode into. 224 Default is kNo_Config. 225 This can be queried with GetDeviceConfig() 226 */ 227 static void SetDeviceConfig(SkBitmap::Config); 228 229 /** @cond UNIT_TEST */ 230 SkDEBUGCODE(static void UnitTest();) 231 /** @endcond */ 232 233 protected: 234 // must be overridden in subclasses. This guy is called by decode(...) 235 virtual bool onDecode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, 236 Mode) = 0; 237 238 /** Can be queried from within onDecode, to see if the user (possibly in 239 a different thread) has requested the decode to cancel. If this returns 240 true, your onDecode() should stop and return false. 241 Each subclass needs to decide how often it can query this, to balance 242 responsiveness with performance. 243 244 Calling this outside of onDecode() may return undefined values. 245 */ 246 247 public: shouldCancelDecode()248 bool shouldCancelDecode() const { return fShouldCancelDecode; } 249 250 protected: 251 SkImageDecoder(); 252 253 // helper function for decoders to handle the (common) case where there is only 254 // once choice available in the image file. 255 bool chooseFromOneChoice(SkBitmap::Config config, int width, int height) const; 256 257 /* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's 258 width/height/rowbytes/config. Returns true on success. This method handles checking 259 for an optional Allocator. 260 */ 261 bool allocPixelRef(SkBitmap*, SkColorTable*) const; 262 263 private: 264 Peeker* fPeeker; 265 Chooser* fChooser; 266 SkBitmap::Allocator* fAllocator; 267 int fSampleSize; 268 bool fDitherImage; 269 mutable bool fShouldCancelDecode; 270 271 // illegal 272 SkImageDecoder(const SkImageDecoder&); 273 SkImageDecoder& operator=(const SkImageDecoder&); 274 }; 275 276 /** Calling newDecoder with a stream returns a new matching imagedecoder 277 instance, or NULL if none can be found. The caller must manage its ownership 278 of the stream as usual, calling unref() when it is done, as the returned 279 decoder may have called ref() (and if so, the decoder is responsible for 280 balancing its ownership when it is destroyed). 281 */ 282 class SkImageDecoderFactory : public SkRefCnt { 283 public: 284 virtual SkImageDecoder* newDecoder(SkStream*) = 0; 285 }; 286 287 class SkDefaultImageDecoderFactory : SkImageDecoderFactory { 288 public: 289 // calls SkImageDecoder::Factory(stream) newDecoder(SkStream * stream)290 virtual SkImageDecoder* newDecoder(SkStream* stream) { 291 return SkImageDecoder::Factory(stream); 292 } 293 }; 294 295 296 #endif 297