1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkImageDecoder.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,540 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkImageDecoder_DEFINED 1.14 +#define SkImageDecoder_DEFINED 1.15 + 1.16 +#include "SkBitmap.h" 1.17 +#include "SkImage.h" 1.18 +#include "SkRect.h" 1.19 +#include "SkRefCnt.h" 1.20 +#include "SkTRegistry.h" 1.21 +#include "SkTypes.h" 1.22 + 1.23 +class SkStream; 1.24 +class SkStreamRewindable; 1.25 + 1.26 +/** \class SkImageDecoder 1.27 + 1.28 + Base class for decoding compressed images into a SkBitmap 1.29 +*/ 1.30 +class SkImageDecoder : public SkNoncopyable { 1.31 +public: 1.32 + virtual ~SkImageDecoder(); 1.33 + 1.34 + enum Format { 1.35 + kUnknown_Format, 1.36 + kBMP_Format, 1.37 + kGIF_Format, 1.38 + kICO_Format, 1.39 + kJPEG_Format, 1.40 + kPNG_Format, 1.41 + kWBMP_Format, 1.42 + kWEBP_Format, 1.43 + 1.44 + kLastKnownFormat = kWEBP_Format, 1.45 + }; 1.46 + 1.47 + /** Return the format of image this decoder can decode. If this decoder can decode multiple 1.48 + formats, kUnknown_Format will be returned. 1.49 + */ 1.50 + virtual Format getFormat() const; 1.51 + 1.52 + /** Return the format of the SkStreamRewindable or kUnknown_Format if it cannot be determined. 1.53 + Rewinds the stream before returning. 1.54 + */ 1.55 + static Format GetStreamFormat(SkStreamRewindable*); 1.56 + 1.57 + /** Return a readable string of the Format provided. 1.58 + */ 1.59 + static const char* GetFormatName(Format); 1.60 + 1.61 + /** Return a readable string of the value returned by getFormat(). 1.62 + */ 1.63 + const char* getFormatName() const; 1.64 + 1.65 + /** Whether the decoder should skip writing zeroes to output if possible. 1.66 + */ 1.67 + bool getSkipWritingZeroes() const { return fSkipWritingZeroes; } 1.68 + 1.69 + /** Set to true if the decoder should skip writing any zeroes when 1.70 + creating the output image. 1.71 + This is a hint that may not be respected by the decoder. 1.72 + It should only be used if it is known that the memory to write 1.73 + to has already been set to 0; otherwise the resulting image will 1.74 + have garbage. 1.75 + This is ideal for images that contain a lot of completely transparent 1.76 + pixels, but may be a performance hit for an image that has only a 1.77 + few transparent pixels. 1.78 + The default is false. 1.79 + */ 1.80 + void setSkipWritingZeroes(bool skip) { fSkipWritingZeroes = skip; } 1.81 + 1.82 + /** Returns true if the decoder should try to dither the resulting image. 1.83 + The default setting is true. 1.84 + */ 1.85 + bool getDitherImage() const { return fDitherImage; } 1.86 + 1.87 + /** Set to true if the the decoder should try to dither the resulting image. 1.88 + The default setting is true. 1.89 + */ 1.90 + void setDitherImage(bool dither) { fDitherImage = dither; } 1.91 + 1.92 + /** Returns true if the decoder should try to decode the 1.93 + resulting image to a higher quality even at the expense of 1.94 + the decoding speed. 1.95 + */ 1.96 + bool getPreferQualityOverSpeed() const { return fPreferQualityOverSpeed; } 1.97 + 1.98 + /** Set to true if the the decoder should try to decode the 1.99 + resulting image to a higher quality even at the expense of 1.100 + the decoding speed. 1.101 + */ 1.102 + void setPreferQualityOverSpeed(bool qualityOverSpeed) { 1.103 + fPreferQualityOverSpeed = qualityOverSpeed; 1.104 + } 1.105 + 1.106 + /** Set to true to require the decoder to return a bitmap with unpremultiplied 1.107 + colors. The default is false, meaning the resulting bitmap will have its 1.108 + colors premultiplied. 1.109 + NOTE: Passing true to this function may result in a bitmap which cannot 1.110 + be properly used by Skia. 1.111 + */ 1.112 + void setRequireUnpremultipliedColors(bool request) { 1.113 + fRequireUnpremultipliedColors = request; 1.114 + } 1.115 + 1.116 + /** Returns true if the decoder will only return bitmaps with unpremultiplied 1.117 + colors. 1.118 + */ 1.119 + bool getRequireUnpremultipliedColors() const { return fRequireUnpremultipliedColors; } 1.120 + 1.121 + /** \class Peeker 1.122 + 1.123 + Base class for optional callbacks to retrieve meta/chunk data out of 1.124 + an image as it is being decoded. 1.125 + */ 1.126 + class Peeker : public SkRefCnt { 1.127 + public: 1.128 + SK_DECLARE_INST_COUNT(Peeker) 1.129 + 1.130 + /** Return true to continue decoding, or false to indicate an error, which 1.131 + will cause the decoder to not return the image. 1.132 + */ 1.133 + virtual bool peek(const char tag[], const void* data, size_t length) = 0; 1.134 + private: 1.135 + typedef SkRefCnt INHERITED; 1.136 + }; 1.137 + 1.138 + Peeker* getPeeker() const { return fPeeker; } 1.139 + Peeker* setPeeker(Peeker*); 1.140 + 1.141 + /** \class Chooser 1.142 + 1.143 + Base class for optional callbacks to choose an image from a format that 1.144 + contains multiple images. 1.145 + */ 1.146 + class Chooser : public SkRefCnt { 1.147 + public: 1.148 + SK_DECLARE_INST_COUNT(Chooser) 1.149 + 1.150 + virtual void begin(int count) {} 1.151 + virtual void inspect(int index, SkBitmap::Config config, int width, int height) {} 1.152 + /** Return the index of the subimage you want, or -1 to choose none of them. 1.153 + */ 1.154 + virtual int choose() = 0; 1.155 + 1.156 + private: 1.157 + typedef SkRefCnt INHERITED; 1.158 + }; 1.159 + 1.160 + Chooser* getChooser() const { return fChooser; } 1.161 + Chooser* setChooser(Chooser*); 1.162 + 1.163 + /** 1.164 + * Optional table describing the caller's preferred config based on 1.165 + * information about the src data. Each field should be set to the 1.166 + * preferred config for a src described in the name of the field. The 1.167 + * src attributes are described in terms of depth (8-index, 1.168 + * 8bit-grayscale, or 8-bits/component) and whether there is per-pixel 1.169 + * alpha (does not apply to grayscale). If the caller has no preference 1.170 + * for a particular src type, its slot should be set to kNo_Config. 1.171 + * 1.172 + * NOTE ABOUT PREFERRED CONFIGS: 1.173 + * If a config is preferred, either using a pref table or as a parameter 1.174 + * to some flavor of decode, it is still at the discretion of the codec 1.175 + * as to what output config is actually returned, as it may not be able 1.176 + * to support the caller's preference. 1.177 + * 1.178 + * If a bitmap is decoded into SkBitmap::A8_Config, the resulting bitmap 1.179 + * will either be a conversion of the grayscale in the case of a 1.180 + * grayscale source or the alpha channel in the case of a source with 1.181 + * an alpha channel. 1.182 + */ 1.183 + struct PrefConfigTable { 1.184 + SkBitmap::Config fPrefFor_8Index_NoAlpha_src; 1.185 + SkBitmap::Config fPrefFor_8Index_YesAlpha_src; 1.186 + SkBitmap::Config fPrefFor_8Gray_src; 1.187 + SkBitmap::Config fPrefFor_8bpc_NoAlpha_src; 1.188 + SkBitmap::Config fPrefFor_8bpc_YesAlpha_src; 1.189 + }; 1.190 + 1.191 + /** 1.192 + * Set an optional table for specifying the caller's preferred config 1.193 + * based on information about the src data. 1.194 + * 1.195 + * The default is no preference, which will assume the config set by 1.196 + * decode is preferred. 1.197 + */ 1.198 + void setPrefConfigTable(const PrefConfigTable&); 1.199 + 1.200 + /** 1.201 + * Do not use a PrefConfigTable to determine the output config. This 1.202 + * is the default, so there is no need to call unless a PrefConfigTable 1.203 + * was previously set. 1.204 + */ 1.205 + void resetPrefConfigTable() { fUsePrefTable = false; } 1.206 + 1.207 + SkBitmap::Allocator* getAllocator() const { return fAllocator; } 1.208 + SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*); 1.209 + 1.210 + // sample-size, if set to > 1, tells the decoder to return a smaller than 1.211 + // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample 1.212 + // size is set to 3, then the returned bitmap will be 1/3 as wide and high, 1.213 + // and will contain 1/9 as many pixels as the original. 1.214 + // Note: this is a hint, and the codec may choose to ignore this, or only 1.215 + // approximate the sample size. 1.216 + int getSampleSize() const { return fSampleSize; } 1.217 + void setSampleSize(int size); 1.218 + 1.219 + /** Reset the sampleSize to its default of 1 1.220 + */ 1.221 + void resetSampleSize() { this->setSampleSize(1); } 1.222 + 1.223 + /** Decoding is synchronous, but for long decodes, a different thread can 1.224 + call this method safely. This sets a state that the decoders will 1.225 + periodically check, and if they see it changed to cancel, they will 1.226 + cancel. This will result in decode() returning false. However, there is 1.227 + no guarantee that the decoder will see the state change in time, so 1.228 + it is possible that cancelDecode() will be called, but will be ignored 1.229 + and decode() will return true (assuming no other problems were 1.230 + encountered). 1.231 + 1.232 + This state is automatically reset at the beginning of decode(). 1.233 + */ 1.234 + void cancelDecode() { 1.235 + // now the subclass must query shouldCancelDecode() to be informed 1.236 + // of the request 1.237 + fShouldCancelDecode = true; 1.238 + } 1.239 + 1.240 + /** Passed to the decode method. If kDecodeBounds_Mode is passed, then 1.241 + only the bitmap's width/height/config need be set. If kDecodePixels_Mode 1.242 + is passed, then the bitmap must have pixels or a pixelRef. 1.243 + */ 1.244 + enum Mode { 1.245 + kDecodeBounds_Mode, //!< only return width/height/config in bitmap 1.246 + kDecodePixels_Mode //!< return entire bitmap (including pixels) 1.247 + }; 1.248 + 1.249 + /** Given a stream, decode it into the specified bitmap. 1.250 + If the decoder can decompress the image, it calls bitmap.setConfig(), 1.251 + and then if the Mode is kDecodePixels_Mode, call allocPixelRef(), 1.252 + which will allocated a pixelRef. To access the pixel memory, the codec 1.253 + needs to call lockPixels/unlockPixels on the 1.254 + bitmap. It can then set the pixels with the decompressed image. 1.255 + * If the image cannot be decompressed, return false. After the 1.256 + * decoding, the function converts the decoded config in bitmap 1.257 + * to pref if possible. Whether a conversion is feasible is 1.258 + * tested by Bitmap::canCopyTo(pref). 1.259 + 1.260 + If an SkBitmap::Allocator is installed via setAllocator, it will be 1.261 + used to allocate the pixel memory. A clever allocator can be used 1.262 + to allocate the memory from a cache, volatile memory, or even from 1.263 + an existing bitmap's memory. 1.264 + 1.265 + If a Peeker is installed via setPeeker, it may be used to peek into 1.266 + meta data during the decode. 1.267 + 1.268 + If a Chooser is installed via setChooser, it may be used to select 1.269 + which image to return from a format that contains multiple images. 1.270 + */ 1.271 + bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode); 1.272 + bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) { 1.273 + return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode); 1.274 + } 1.275 + 1.276 + /** 1.277 + * Given a stream, build an index for doing tile-based decode. 1.278 + * The built index will be saved in the decoder, and the image size will 1.279 + * be returned in width and height. 1.280 + * 1.281 + * Return true for success or false on failure. 1.282 + */ 1.283 + bool buildTileIndex(SkStreamRewindable*, int *width, int *height); 1.284 + 1.285 + /** 1.286 + * Decode a rectangle subset in the image. 1.287 + * The method can only be called after buildTileIndex(). 1.288 + * 1.289 + * Return true for success. 1.290 + * Return false if the index is never built or failing in decoding. 1.291 + */ 1.292 + bool decodeSubset(SkBitmap* bm, const SkIRect& subset, SkBitmap::Config pref); 1.293 + 1.294 + SK_ATTR_DEPRECATED("use decodeSubset() instead") 1.295 + bool decodeRegion(SkBitmap* bitmap, const SkIRect& rect, SkBitmap::Config pref) { 1.296 + return this->decodeSubset(bitmap, rect, pref); 1.297 + } 1.298 + 1.299 + /** Given a stream, this will try to find an appropriate decoder object. 1.300 + If none is found, the method returns NULL. 1.301 + */ 1.302 + static SkImageDecoder* Factory(SkStreamRewindable*); 1.303 + 1.304 + /** Decode the image stored in the specified file, and store the result 1.305 + in bitmap. Return true for success or false on failure. 1.306 + 1.307 + @param prefConfig If the PrefConfigTable is not set, prefer this config. 1.308 + See NOTE ABOUT PREFERRED CONFIGS. 1.309 + 1.310 + @param format On success, if format is non-null, it is set to the format 1.311 + of the decoded file. On failure it is ignored. 1.312 + */ 1.313 + static bool DecodeFile(const char file[], SkBitmap* bitmap, 1.314 + SkBitmap::Config prefConfig, Mode, 1.315 + Format* format = NULL); 1.316 + static bool DecodeFile(const char file[], SkBitmap* bitmap) { 1.317 + return DecodeFile(file, bitmap, SkBitmap::kNo_Config, 1.318 + kDecodePixels_Mode, NULL); 1.319 + } 1.320 + /** Decode the image stored in the specified memory buffer, and store the 1.321 + result in bitmap. Return true for success or false on failure. 1.322 + 1.323 + @param prefConfig If the PrefConfigTable is not set, prefer this config. 1.324 + See NOTE ABOUT PREFERRED CONFIGS. 1.325 + 1.326 + @param format On success, if format is non-null, it is set to the format 1.327 + of the decoded buffer. On failure it is ignored. 1.328 + */ 1.329 + static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap, 1.330 + SkBitmap::Config prefConfig, Mode, 1.331 + Format* format = NULL); 1.332 + static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap){ 1.333 + return DecodeMemory(buffer, size, bitmap, SkBitmap::kNo_Config, 1.334 + kDecodePixels_Mode, NULL); 1.335 + } 1.336 + 1.337 + /** 1.338 + * Struct containing information about a pixel destination. 1.339 + */ 1.340 + struct Target { 1.341 + /** 1.342 + * Pre-allocated memory. 1.343 + */ 1.344 + void* fAddr; 1.345 + 1.346 + /** 1.347 + * Rowbytes of the allocated memory. 1.348 + */ 1.349 + size_t fRowBytes; 1.350 + }; 1.351 + 1.352 + /** Decode the image stored in the specified SkStreamRewindable, and store the result 1.353 + in bitmap. Return true for success or false on failure. 1.354 + 1.355 + @param prefConfig If the PrefConfigTable is not set, prefer this config. 1.356 + See NOTE ABOUT PREFERRED CONFIGS. 1.357 + 1.358 + @param format On success, if format is non-null, it is set to the format 1.359 + of the decoded stream. On failure it is ignored. 1.360 + */ 1.361 + static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap, 1.362 + SkBitmap::Config prefConfig, Mode, 1.363 + Format* format = NULL); 1.364 + static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap) { 1.365 + return DecodeStream(stream, bitmap, SkBitmap::kNo_Config, 1.366 + kDecodePixels_Mode, NULL); 1.367 + } 1.368 + 1.369 + /** Return the default config for the running device. 1.370 + Currently this used as a suggestion to image decoders that need to guess 1.371 + what config they should decode into. 1.372 + Default is kNo_Config, but this can be changed with SetDeviceConfig() 1.373 + */ 1.374 + static SkBitmap::Config GetDeviceConfig(); 1.375 + /** Set the default config for the running device. 1.376 + Currently this used as a suggestion to image decoders that need to guess 1.377 + what config they should decode into. 1.378 + Default is kNo_Config. 1.379 + This can be queried with GetDeviceConfig() 1.380 + */ 1.381 + static void SetDeviceConfig(SkBitmap::Config); 1.382 + 1.383 +protected: 1.384 + // must be overridden in subclasses. This guy is called by decode(...) 1.385 + virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0; 1.386 + 1.387 + // If the decoder wants to support tiled based decoding, 1.388 + // this method must be overridden. This guy is called by buildTileIndex(...) 1.389 + virtual bool onBuildTileIndex(SkStreamRewindable*, int *width, int *height) { 1.390 + return false; 1.391 + } 1.392 + 1.393 + // If the decoder wants to support tiled based decoding, 1.394 + // this method must be overridden. This guy is called by decodeRegion(...) 1.395 + virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) { 1.396 + return false; 1.397 + } 1.398 + 1.399 + /* 1.400 + * Crop a rectangle from the src Bitmap to the dest Bitmap. src and dst are 1.401 + * both sampled by sampleSize from an original Bitmap. 1.402 + * 1.403 + * @param dst the destination bitmap. 1.404 + * @param src the source bitmap that is sampled by sampleSize from the 1.405 + * original bitmap. 1.406 + * @param sampleSize the sample size that src is sampled from the original bitmap. 1.407 + * @param (dstX, dstY) the upper-left point of the dest bitmap in terms of 1.408 + * the coordinate in the original bitmap. 1.409 + * @param (width, height) the width and height of the unsampled dst. 1.410 + * @param (srcX, srcY) the upper-left point of the src bitmap in terms of 1.411 + * the coordinate in the original bitmap. 1.412 + * @return bool Whether or not it succeeded. 1.413 + */ 1.414 + bool cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, 1.415 + int dstX, int dstY, int width, int height, 1.416 + int srcX, int srcY); 1.417 + 1.418 + /** 1.419 + * Copy all fields on this decoder to the other decoder. Used by subclasses 1.420 + * to decode a subimage using a different decoder, but with the same settings. 1.421 + */ 1.422 + void copyFieldsToOther(SkImageDecoder* other); 1.423 + 1.424 + /** 1.425 + * Return the default preference being used by the current or latest call to 1.426 + * decode. 1.427 + */ 1.428 + SkBitmap::Config getDefaultPref() { return fDefaultPref; } 1.429 + 1.430 + /** Can be queried from within onDecode, to see if the user (possibly in 1.431 + a different thread) has requested the decode to cancel. If this returns 1.432 + true, your onDecode() should stop and return false. 1.433 + Each subclass needs to decide how often it can query this, to balance 1.434 + responsiveness with performance. 1.435 + 1.436 + Calling this outside of onDecode() may return undefined values. 1.437 + */ 1.438 + 1.439 +public: 1.440 + bool shouldCancelDecode() const { return fShouldCancelDecode; } 1.441 + 1.442 +protected: 1.443 + SkImageDecoder(); 1.444 + 1.445 + // helper function for decoders to handle the (common) case where there is only 1.446 + // once choice available in the image file. 1.447 + bool chooseFromOneChoice(SkBitmap::Config config, int width, int height) const; 1.448 + 1.449 + /* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's 1.450 + width/height/rowbytes/config. Returns true on success. This method handles checking 1.451 + for an optional Allocator. 1.452 + */ 1.453 + bool allocPixelRef(SkBitmap*, SkColorTable*) const; 1.454 + 1.455 + /** 1.456 + * The raw data of the src image. 1.457 + */ 1.458 + enum SrcDepth { 1.459 + // Color-indexed. 1.460 + kIndex_SrcDepth, 1.461 + // Grayscale in 8 bits. 1.462 + k8BitGray_SrcDepth, 1.463 + // 8 bits per component. Used for 24 bit if there is no alpha. 1.464 + k32Bit_SrcDepth, 1.465 + }; 1.466 + /** The subclass, inside onDecode(), calls this to determine the config of 1.467 + the returned bitmap. SrcDepth and hasAlpha reflect the raw data of the 1.468 + src image. This routine returns the caller's preference given 1.469 + srcDepth and hasAlpha, or kNo_Config if there is no preference. 1.470 + 1.471 + Note: this also takes into account GetDeviceConfig(), so the subclass 1.472 + need not call that. 1.473 + */ 1.474 + SkBitmap::Config getPrefConfig(SrcDepth, bool hasAlpha) const; 1.475 + 1.476 +private: 1.477 + Peeker* fPeeker; 1.478 + Chooser* fChooser; 1.479 + SkBitmap::Allocator* fAllocator; 1.480 + int fSampleSize; 1.481 + SkBitmap::Config fDefaultPref; // use if fUsePrefTable is false 1.482 + PrefConfigTable fPrefTable; // use if fUsePrefTable is true 1.483 + bool fDitherImage; 1.484 + bool fUsePrefTable; 1.485 + bool fSkipWritingZeroes; 1.486 + mutable bool fShouldCancelDecode; 1.487 + bool fPreferQualityOverSpeed; 1.488 + bool fRequireUnpremultipliedColors; 1.489 +}; 1.490 + 1.491 +/** Calling newDecoder with a stream returns a new matching imagedecoder 1.492 + instance, or NULL if none can be found. The caller must manage its ownership 1.493 + of the stream as usual, calling unref() when it is done, as the returned 1.494 + decoder may have called ref() (and if so, the decoder is responsible for 1.495 + balancing its ownership when it is destroyed). 1.496 + */ 1.497 +class SkImageDecoderFactory : public SkRefCnt { 1.498 +public: 1.499 + SK_DECLARE_INST_COUNT(SkImageDecoderFactory) 1.500 + 1.501 + virtual SkImageDecoder* newDecoder(SkStreamRewindable*) = 0; 1.502 + 1.503 +private: 1.504 + typedef SkRefCnt INHERITED; 1.505 +}; 1.506 + 1.507 +class SkDefaultImageDecoderFactory : SkImageDecoderFactory { 1.508 +public: 1.509 + // calls SkImageDecoder::Factory(stream) 1.510 + virtual SkImageDecoder* newDecoder(SkStreamRewindable* stream) { 1.511 + return SkImageDecoder::Factory(stream); 1.512 + } 1.513 +}; 1.514 + 1.515 +// This macro declares a global (i.e., non-class owned) creation entry point 1.516 +// for each decoder (e.g., CreateJPEGImageDecoder) 1.517 +#define DECLARE_DECODER_CREATOR(codec) \ 1.518 + SkImageDecoder *Create ## codec (); 1.519 + 1.520 +// This macro defines the global creation entry point for each decoder. Each 1.521 +// decoder implementation that registers with the decoder factory must call it. 1.522 +#define DEFINE_DECODER_CREATOR(codec) \ 1.523 + SkImageDecoder *Create ## codec () { \ 1.524 + return SkNEW( Sk ## codec ); \ 1.525 + } 1.526 + 1.527 +// All the decoders known by Skia. Note that, depending on the compiler settings, 1.528 +// not all of these will be available 1.529 +DECLARE_DECODER_CREATOR(BMPImageDecoder); 1.530 +DECLARE_DECODER_CREATOR(GIFImageDecoder); 1.531 +DECLARE_DECODER_CREATOR(ICOImageDecoder); 1.532 +DECLARE_DECODER_CREATOR(JPEGImageDecoder); 1.533 +DECLARE_DECODER_CREATOR(PNGImageDecoder); 1.534 +DECLARE_DECODER_CREATOR(WBMPImageDecoder); 1.535 +DECLARE_DECODER_CREATOR(WEBPImageDecoder); 1.536 + 1.537 + 1.538 +// Typedefs to make registering decoder and formatter callbacks easier. 1.539 +// These have to be defined outside SkImageDecoder. :( 1.540 +typedef SkTRegistry<SkImageDecoder*(*)(SkStreamRewindable*)> SkImageDecoder_DecodeReg; 1.541 +typedef SkTRegistry<SkImageDecoder::Format(*)(SkStreamRewindable*)> SkImageDecoder_FormatReg; 1.542 + 1.543 +#endif