grab from latest android



git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h
new file mode 100644
index 0000000..4a18cab
--- /dev/null
+++ b/include/images/SkImageDecoder.h
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkImageDecoder_DEFINED
+#define SkImageDecoder_DEFINED
+
+#include "SkBitmap.h"
+#include "SkRefCnt.h"
+
+class SkStream;
+
+/** \class SkImageDecoder
+
+    Base class for decoding compressed images into a SkBitmap
+*/
+class SkImageDecoder {
+public:
+    virtual ~SkImageDecoder();
+    
+    enum Format {
+        kUnknown_Format,
+        kBMP_Format,
+        kGIF_Format,
+        kICO_Format,
+        kJPEG_Format,
+        kPNG_Format,
+        kWBMP_Format,
+        
+        kLastKnownFormat = kWBMP_Format
+    };
+        
+    /** Return the compressed data's format (see Format enum)
+    */
+    virtual Format getFormat() const;
+
+    /** Returns true if the decoder should try to dither the resulting image.
+        The default setting is true.
+    */
+    bool getDitherImage() const { return fDitherImage; }
+    
+    /** Set to true if the the decoder should try to dither the resulting image.
+        The default setting is true.
+    */
+    void setDitherImage(bool dither) { fDitherImage = dither; }
+
+    /** \class Peeker
+    
+        Base class for optional callbacks to retrieve meta/chunk data out of
+        an image as it is being decoded.
+    */
+    class Peeker : public SkRefCnt {
+    public:
+        /** Return true to continue decoding, or false to indicate an error, which
+            will cause the decoder to not return the image.
+        */
+        virtual bool peek(const char tag[], const void* data, size_t length) = 0;
+    };
+
+    Peeker* getPeeker() const { return fPeeker; }
+    Peeker* setPeeker(Peeker*);
+    
+    /** \class Peeker
+    
+        Base class for optional callbacks to retrieve meta/chunk data out of
+        an image as it is being decoded.
+    */
+    class Chooser : public SkRefCnt {
+    public:
+        virtual void begin(int count) {}
+        virtual void inspect(int index, SkBitmap::Config config, int width, int height) {}
+        /** Return the index of the subimage you want, or -1 to choose none of them.
+        */
+        virtual int choose() = 0;
+    };
+
+    Chooser* getChooser() const { return fChooser; }
+    Chooser* setChooser(Chooser*);
+
+    SkBitmap::Allocator* getAllocator() const { return fAllocator; }
+    SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*);
+
+    // sample-size, if set to > 1, tells the decoder to return a smaller than
+    // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample
+    // size is set to 3, then the returned bitmap will be 1/3 as wide and high,
+    // and will contain 1/9 as many pixels as the original.
+    // Note: this is a hint, and the codec may choose to ignore this, or only
+    // approximate the sample size.
+    int getSampleSize() const { return fSampleSize; }
+    void setSampleSize(int size);
+    
+    /** Reset the sampleSize to its default of 1
+     */
+    void resetSampleSize() { this->setSampleSize(1); }
+
+    /** Decoding is synchronous, but for long decodes, a different thread can
+        call this method safely. This sets a state that the decoders will
+        periodically check, and if they see it changed to cancel, they will
+        cancel. This will result in decode() returning false. However, there is
+        no guarantee that the decoder will see the state change in time, so
+        it is possible that cancelDecode() will be called, but will be ignored
+        and decode() will return true (assuming no other problems were
+        encountered).
+     
+        This state is automatically reset at the beginning of decode().
+     */
+    void cancelDecode() {
+        // now the subclass must query shouldCancelDecode() to be informed
+        // of the request
+        fShouldCancelDecode = true;
+    }
+
+    /** Passed to the decode method. If kDecodeBounds_Mode is passed, then
+        only the bitmap's width/height/config need be set. If kDecodePixels_Mode
+        is passed, then the bitmap must have pixels or a pixelRef.
+    */
+    enum Mode {
+        kDecodeBounds_Mode, //!< only return width/height/config in bitmap
+        kDecodePixels_Mode  //!< return entire bitmap (including pixels)
+    };
+    
+    /** Given a stream, decode it into the specified bitmap.
+        If the decoder can decompress the image, it calls bitmap.setConfig(),
+        and then if the Mode is kDecodePixels_Mode, call allocPixelRef(),
+        which will allocated a pixelRef. To access the pixel memory, the codec
+        needs to call lockPixels/unlockPixels on the
+        bitmap. It can then set the pixels with the decompressed image.
+        If the image cannot be decompressed, return false.
+        
+        note: document use of Allocator, Peeker and Chooser 
+    */
+    bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode);
+
+    /** Given a stream, this will try to find an appropriate decoder object.
+        If none is found, the method returns NULL.
+    */
+    static SkImageDecoder* Factory(SkStream*);
+    
+    /** Decode the image stored in the specified file, and store the result
+        in bitmap. Return true for success or false on failure.
+
+        If pref is kNo_Config, then the decoder is free to choose the most natural
+        config given the image data. If pref something other than kNo_Config,
+        the decoder will attempt to decode the image into that format, unless
+        there is a conflict (e.g. the image has per-pixel alpha and the bitmap's
+        config does not support that), in which case the decoder will choose a
+        closest match configuration.
+    */
+    static bool DecodeFile(const char file[], SkBitmap* bitmap,
+                             SkBitmap::Config prefConfig, Mode);
+    static bool DecodeFile(const char file[], SkBitmap* bitmap)
+    {
+        return DecodeFile(file, bitmap, SkBitmap::kNo_Config, kDecodePixels_Mode);
+    }
+    /** Decode the image stored in the specified memory buffer, and store the
+        result in bitmap. Return true for success or false on failure.
+
+        If pref is kNo_Config, then the decoder is free to choose the most natural
+        config given the image data. If pref something other than kNo_Config,
+        the decoder will attempt to decode the image into that format, unless
+        there is a conflict (e.g. the image has per-pixel alpha and the bitmap's
+        config does not support that), in which case the decoder will choose a
+        closest match configuration.
+    */
+    static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap,
+                             SkBitmap::Config prefConfig, Mode);
+    static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap)
+    {
+        return DecodeMemory(buffer, size, bitmap, SkBitmap::kNo_Config,
+                            kDecodePixels_Mode);
+    }
+    /** Decode the image stored in the specified SkStream, and store the result
+        in bitmap. Return true for success or false on failure.
+
+        If pref is kNo_Config, then the decoder is free to choose the most
+        natural config given the image data. If pref something other than
+        kNo_Config, the decoder will attempt to decode the image into that
+        format, unless there is a conflict (e.g. the image has per-pixel alpha
+        and the bitmap's config does not support that), in which case the
+        decoder will choose a closest match configuration.
+    */
+    static bool DecodeStream(SkStream* stream, SkBitmap* bitmap,
+                             SkBitmap::Config prefConfig, Mode);
+    static bool DecodeStream(SkStream* stream, SkBitmap* bitmap)
+    {
+        return DecodeStream(stream, bitmap, SkBitmap::kNo_Config,
+                            kDecodePixels_Mode);
+    }
+    
+    /*  Given a format, return true if there is a currently installed decoder
+        for that format. Since a given build may not include all codecs (to save
+        code-size), this may return false.
+    */
+    static bool SupportsFormat(Format);
+
+    /** Return the default config for the running device.
+        Currently this used as a suggestion to image decoders that need to guess
+        what config they should decode into.
+        Default is kNo_Config, but this can be changed with SetDeviceConfig()
+    */
+    static SkBitmap::Config GetDeviceConfig();
+    /** Set the default config for the running device.
+        Currently this used as a suggestion to image decoders that need to guess
+        what config they should decode into.
+        Default is kNo_Config.
+        This can be queried with GetDeviceConfig()
+    */
+    static void SetDeviceConfig(SkBitmap::Config);
+
+  /** @cond UNIT_TEST */
+    SkDEBUGCODE(static void UnitTest();)
+  /** @endcond */
+
+protected:
+    // must be overridden in subclasses. This guy is called by decode(...)
+    virtual bool onDecode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref,
+                          Mode) = 0;
+
+    /** Can be queried from within onDecode, to see if the user (possibly in
+        a different thread) has requested the decode to cancel. If this returns
+        true, your onDecode() should stop and return false.
+        Each subclass needs to decide how often it can query this, to balance
+        responsiveness with performance.
+     
+        Calling this outside of onDecode() may return undefined values.
+     */
+
+public:
+    bool shouldCancelDecode() const { return fShouldCancelDecode; }
+
+protected:    
+    SkImageDecoder();
+
+    // helper function for decoders to handle the (common) case where there is only
+    // once choice available in the image file.
+    bool chooseFromOneChoice(SkBitmap::Config config, int width, int height) const;
+
+    /*  Helper for subclasses. Call this to allocate the pixel memory given the bitmap's
+        width/height/rowbytes/config. Returns true on success. This method handles checking
+        for an optional Allocator.
+    */
+    bool allocPixelRef(SkBitmap*, SkColorTable*) const;
+
+private:
+    Peeker*                 fPeeker;
+    Chooser*                fChooser;
+    SkBitmap::Allocator*    fAllocator;
+    int                     fSampleSize;
+    bool                    fDitherImage;
+    mutable bool            fShouldCancelDecode;
+
+    // illegal
+    SkImageDecoder(const SkImageDecoder&);
+    SkImageDecoder& operator=(const SkImageDecoder&);
+};
+
+#ifdef SK_SUPPORT_IMAGE_ENCODE
+
+class SkWStream;
+
+class SkImageEncoder {
+public:
+    enum Type {
+        kJPEG_Type,
+        kPNG_Type
+    };
+    static SkImageEncoder* Create(Type);
+
+    virtual ~SkImageEncoder();
+    
+    /*  Quality ranges from 0..100 */
+
+    bool encodeFile(const char file[], const SkBitmap&, int quality = 80);
+    bool encodeStream(SkWStream*, const SkBitmap&, int quality = 80);
+
+    static bool EncodeFile(const char file[], const SkBitmap&, Type,
+                           int quality = 80);
+    static bool EncodeStream(SkWStream*, const SkBitmap&, Type,
+                           int quality = 80);
+
+protected:
+    virtual bool onEncode(SkWStream*, const SkBitmap&, int quality) = 0;
+};
+
+#endif /* SK_SUPPORT_IMAGE_ENCODE */
+
+///////////////////////////////////////////////////////////////////////
+
+#endif