aboutsummaryrefslogtreecommitdiffstats
path: root/include/images
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:21 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:21 -0800
commit03202c9c3dfbf8c4feb0a1ee9b3680817e633f58 (patch)
tree1d0ba7cbf3e77c239527697ac455312b216c434e /include/images
parent37df15a82319228ae28fe5d99c010b288aad7091 (diff)
downloadexternal_skia-03202c9c3dfbf8c4feb0a1ee9b3680817e633f58.zip
external_skia-03202c9c3dfbf8c4feb0a1ee9b3680817e633f58.tar.gz
external_skia-03202c9c3dfbf8c4feb0a1ee9b3680817e633f58.tar.bz2
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'include/images')
-rw-r--r--include/images/SkFlipPixelRef.h114
-rw-r--r--include/images/SkImageDecoder.h269
-rw-r--r--include/images/SkImageEncoder.h36
-rw-r--r--include/images/SkImageRef.h97
-rw-r--r--include/images/SkImageRef_GlobalPool.h72
-rw-r--r--include/images/SkMovie.h83
-rw-r--r--include/images/SkPageFlipper.h70
7 files changed, 741 insertions, 0 deletions
diff --git a/include/images/SkFlipPixelRef.h b/include/images/SkFlipPixelRef.h
new file mode 100644
index 0000000..3b4e97a
--- /dev/null
+++ b/include/images/SkFlipPixelRef.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2008 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 SkFlipPixelRef_DEFINED
+#define SkFlipPixelRef_DEFINED
+
+#include "SkBitmap.h"
+#include "SkPageFlipper.h"
+#include "SkPixelRef.h"
+#include "SkThread.h"
+
+class SkRegion;
+
+class SkFlipPixelRef : public SkPixelRef {
+public:
+ SkFlipPixelRef(SkBitmap::Config, int width, int height);
+ virtual ~SkFlipPixelRef();
+
+ bool isDirty() const { return fFlipper.isDirty(); }
+ const SkRegion& dirtyRgn() const { return fFlipper.dirtyRgn(); }
+
+ void inval() { fFlipper.inval(); }
+ void inval(const SkIRect& rect) { fFlipper.inval(rect); }
+ void inval(const SkRegion& rgn) { fFlipper.inval(rgn); }
+ void inval(const SkRect& r, bool doAA) { fFlipper.inval(r, doAA); }
+
+ const SkRegion& beginUpdate(SkBitmap* device);
+ void endUpdate();
+
+private:
+ void getFrontBack(const void** front, void** back) const {
+ if (front) {
+ *front = fPage0;
+ }
+ if (back) {
+ *back = fPage1;
+ }
+ }
+
+ void swapPages();
+
+ // Helper to copy pixels from srcAddr to the dst bitmap, clipped to clip.
+ // srcAddr points to memory with the same config as dst.
+ static void CopyBitsFromAddr(const SkBitmap& dst, const SkRegion& clip,
+ const void* srcAddr);
+
+ // serialization
+
+public:
+ virtual Factory getFactory() const { return Create; }
+ virtual void flatten(SkFlattenableWriteBuffer&) const;
+ static SkPixelRef* Create(SkFlattenableReadBuffer& buffer);
+
+protected:
+ virtual void* onLockPixels(SkColorTable**);
+ virtual void onUnlockPixels();
+
+ SkFlipPixelRef(SkFlattenableReadBuffer&);
+
+private:
+ SkMutex fMutex;
+ SkPageFlipper fFlipper;
+
+ void* fStorage;
+ void* fPage0; // points into fStorage;
+ void* fPage1; // points into fStorage;
+ size_t fSize; // size of 1 page. fStorage holds 2 pages
+ SkBitmap::Config fConfig;
+
+ typedef SkPixelRef INHERITED;
+};
+
+class SkAutoFlipUpdate : SkNoncopyable {
+public:
+ SkAutoFlipUpdate(SkFlipPixelRef* ref) : fRef(ref) {
+ fDirty = &ref->beginUpdate(&fBitmap);
+ }
+ ~SkAutoFlipUpdate() {
+ if (fRef) {
+ fRef->endUpdate();
+ }
+ }
+
+ const SkBitmap& bitmap() const { return fBitmap; }
+ const SkRegion& dirty() const { return *fDirty; }
+
+ // optional. This gets automatically called in the destructor (only once)
+ void endUpdate() {
+ if (fRef) {
+ fRef->endUpdate();
+ fRef = NULL;
+ }
+ }
+
+private:
+ SkFlipPixelRef* fRef;
+ SkBitmap fBitmap;
+ const SkRegion* fDirty;
+};
+
+#endif
diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h
new file mode 100644
index 0000000..5b91c51
--- /dev/null
+++ b/include/images/SkImageDecoder.h
@@ -0,0 +1,269 @@
+/*
+ * 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&);
+};
+
+#endif
diff --git a/include/images/SkImageEncoder.h b/include/images/SkImageEncoder.h
new file mode 100644
index 0000000..94989c0
--- /dev/null
+++ b/include/images/SkImageEncoder.h
@@ -0,0 +1,36 @@
+#ifndef SkImageEncoder_DEFINED
+#define SkImageEncoder_DEFINED
+
+#include "SkTypes.h"
+
+class SkBitmap;
+class SkWStream;
+
+class SkImageEncoder {
+public:
+ enum Type {
+ kJPEG_Type,
+ kPNG_Type
+ };
+ static SkImageEncoder* Create(Type);
+
+ virtual ~SkImageEncoder();
+
+ /* Quality ranges from 0..100 */
+ enum {
+ kDefaultQuality = 80
+ };
+
+ bool encodeFile(const char file[], const SkBitmap&, int quality);
+ bool encodeStream(SkWStream*, const SkBitmap&, int quality);
+
+ static bool EncodeFile(const char file[], const SkBitmap&, Type,
+ int quality);
+ static bool EncodeStream(SkWStream*, const SkBitmap&, Type,
+ int quality);
+
+protected:
+ virtual bool onEncode(SkWStream*, const SkBitmap&, int quality) = 0;
+};
+
+#endif
diff --git a/include/images/SkImageRef.h b/include/images/SkImageRef.h
new file mode 100644
index 0000000..e94b7d4
--- /dev/null
+++ b/include/images/SkImageRef.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 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 SkImageRef_DEFINED
+#define SkImageRef_DEFINED
+
+#include "SkPixelRef.h"
+#include "SkBitmap.h"
+#include "SkImageDecoder.h"
+#include "SkString.h"
+
+class SkImageRefPool;
+class SkStream;
+
+// define this to enable dumping whenever we add/remove/purge an imageref
+//#define DUMP_IMAGEREF_LIFECYCLE
+
+class SkImageRef : public SkPixelRef {
+public:
+ /** Create a new imageref from a stream. NOTE: the stream is not copied, but
+ since it may be accessed from another thread, the caller must ensure
+ that this imageref is the only owner of the stream. i.e. - sole
+ ownership of the stream object is transferred to this imageref object.
+
+ @param stream The stream containing the encoded image data. Ownership
+ of this stream is transferred to the imageref, and
+ therefore the stream's ownercount must be 1.
+ @param config The preferred config of the decoded bitmap.
+ @param sampleSize Requested sampleSize for decoding. Defaults to 1.
+ */
+ SkImageRef(SkStream*, SkBitmap::Config config, int sampleSize = 1);
+ virtual ~SkImageRef();
+
+ /** Return true if the image can be decoded. If so, and bitmap is non-null,
+ call its setConfig() with the corresponding values, but explicitly will
+ not set its pixels or colortable. Use SkPixelRef::lockPixels() for that.
+
+ If there has been an error decoding the bitmap, this will return false
+ and ignore the bitmap parameter.
+ */
+ bool getInfo(SkBitmap* bm);
+
+ // overrides
+ virtual void flatten(SkFlattenableWriteBuffer&) const;
+
+protected:
+ /** Override if you want to install a custom allocator.
+ When this is called we will have already acquired the mutex!
+ */
+ virtual bool onDecode(SkImageDecoder* codec, SkStream*, SkBitmap*,
+ SkBitmap::Config, SkImageDecoder::Mode);
+
+ /* Overrides from SkPixelRef
+ When these are called, we will have already acquired the mutex!
+ */
+
+ virtual void* onLockPixels(SkColorTable**);
+ // override this in your subclass to clean up when we're unlocking pixels
+ virtual void onUnlockPixels();
+
+ SkImageRef(SkFlattenableReadBuffer&);
+
+ SkBitmap fBitmap;
+
+private:
+ SkStream* setStream(SkStream*);
+ // called with mutex already held. returns true if the bitmap is in the
+ // requested state (or further, i.e. has pixels)
+ bool prepareBitmap(SkImageDecoder::Mode);
+
+ SkStream* fStream;
+ SkBitmap::Config fConfig;
+ int fSampleSize;
+ bool fErrorInDecoding;
+
+ friend class SkImageRefPool;
+
+ SkImageRef* fPrev, *fNext;
+ size_t ramUsed() const;
+
+ typedef SkPixelRef INHERITED;
+};
+
+#endif
diff --git a/include/images/SkImageRef_GlobalPool.h b/include/images/SkImageRef_GlobalPool.h
new file mode 100644
index 0000000..a9d4dce
--- /dev/null
+++ b/include/images/SkImageRef_GlobalPool.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 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 SkImageRef_GlobalPool_DEFINED
+#define SkImageRef_GlobalPool_DEFINED
+
+#include "SkImageRef.h"
+
+class SkImageRef_GlobalPool : public SkImageRef {
+public:
+ // if pool is null, use the global pool
+ SkImageRef_GlobalPool(SkStream*, SkBitmap::Config, int sampleSize = 1);
+ virtual ~SkImageRef_GlobalPool();
+
+ // overrides
+ virtual Factory getFactory() const {
+ return Create;
+ }
+ static SkPixelRef* Create(SkFlattenableReadBuffer&);
+
+ // API to control the global pool
+
+ /** Return the amount specified as the budget for the cache (in bytes).
+ */
+ static size_t GetRAMBudget();
+
+ /** Set a new budget value for the cache.
+ */
+ static void SetRAMBudget(size_t);
+
+ /** Return how much ram is currently in use by the global cache.
+ */
+ static size_t GetRAMUsed();
+
+ /** Free up (approximately) enough such that the amount used by the cache
+ is <= the specified amount. Since some images may be "in use", the
+ amount actually freed may not always result in a ram usage value <=
+ to the requested amount. In addition, because of the
+ chunky nature of the cache, the resulting usage may be < the requested
+ amount.
+ */
+ static void SetRAMUsed(size_t usageInBytes);
+
+ static void DumpPool();
+
+protected:
+ virtual bool onDecode(SkImageDecoder* codec, SkStream* stream,
+ SkBitmap* bitmap, SkBitmap::Config config,
+ SkImageDecoder::Mode mode);
+
+ virtual void onUnlockPixels();
+
+ SkImageRef_GlobalPool(SkFlattenableReadBuffer&);
+
+private:
+ typedef SkImageRef INHERITED;
+};
+
+#endif
diff --git a/include/images/SkMovie.h b/include/images/SkMovie.h
new file mode 100644
index 0000000..45962a5
--- /dev/null
+++ b/include/images/SkMovie.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 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 SkMovie_DEFINED
+#define SkMovie_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkCanvas.h"
+
+class SkStream;
+
+class SkMovie : public SkRefCnt {
+public:
+ /** Try to create a movie from the stream. If the stream format is not
+ supported, return NULL.
+ */
+ static SkMovie* DecodeStream(SkStream*);
+ /** Try to create a movie from the specified file path. If the file is not
+ found, or the format is not supported, return NULL. If a movie is
+ returned, the stream may be retained by the movie (via ref()) until
+ the movie is finished with it (by calling unref()).
+ */
+ static SkMovie* DecodeFile(const char path[]);
+ /** Try to create a movie from the specified memory.
+ If the format is not supported, return NULL. If a movie is returned,
+ the data will have been read or copied, and so the caller may free
+ it.
+ */
+ static SkMovie* DecodeMemory(const void* data, size_t length);
+
+ SkMSec duration();
+ int width();
+ int height();
+ int isOpaque();
+
+ /** Specify the time code (between 0...duration) to sample a bitmap
+ from the movie. Returns true if this time code generated a different
+ bitmap/frame from the previous state (i.e. true means you need to
+ redraw).
+ */
+ bool setTime(SkMSec);
+
+ // return the right bitmap for the current time code
+ const SkBitmap& bitmap();
+
+protected:
+ struct Info {
+ SkMSec fDuration;
+ int fWidth;
+ int fHeight;
+ bool fIsOpaque;
+ };
+
+ virtual bool onGetInfo(Info*) = 0;
+ virtual bool onSetTime(SkMSec) = 0;
+ virtual bool onGetBitmap(SkBitmap*) = 0;
+
+ // visible for subclasses
+ SkMovie();
+
+private:
+ Info fInfo;
+ SkMSec fCurrTime;
+ SkBitmap fBitmap;
+ bool fNeedBitmap;
+
+ void ensureInfo();
+};
+
+#endif
diff --git a/include/images/SkPageFlipper.h b/include/images/SkPageFlipper.h
new file mode 100644
index 0000000..0d791ee
--- /dev/null
+++ b/include/images/SkPageFlipper.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008 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 SkPageFlipper_DEFINED
+#define SkPageFlipper_DEFINED
+
+#include "SkRegion.h"
+
+/** SkPageFlipper manages alternating inval/dirty regions for a rectangular area
+ (like a bitmap). You call inval() to accumulate inval areas, and then when
+ you're ready to "flip" pages (i.e. draw into the one you've been
+ invalidating) you call update, which swaps the inval regions, and returns
+ two things to you: 1) the final inval region to be drawn into, and 2) the
+ region of pixels that should be copied from the "front" page onto the one
+ you're about to draw into. This copyBits region will be disjoint from the
+ inval region, so both need to be handled.
+ */
+class SkPageFlipper {
+public:
+ SkPageFlipper();
+ SkPageFlipper(int width, int height);
+
+ int width() const { return fWidth; }
+ int height() const { return fHeight; }
+
+ void resize(int width, int height);
+
+ bool isDirty() const { return !fDirty1->isEmpty(); }
+ const SkRegion& dirtyRgn() const { return *fDirty1; }
+
+ void inval();
+ void inval(const SkIRect&);
+ void inval(const SkRegion&);
+ void inval(const SkRect&, bool antialias);
+
+ /** When you're ready to write to the back page, call update. The returned
+ region is the invalidate are that needs to be drawn to. The copyBits
+ region (provided by the caller) is the area that should be copied from
+ the front page to the back page (will not intersect with the returned
+ inval region.
+
+ Once this is called, the two internal regions are swapped, so the *new*
+ back inval region is ready to receive new inval calls.
+ */
+ const SkRegion& update(SkRegion* copyBits);
+
+private:
+ SkRegion* fDirty0;
+ SkRegion* fDirty1;
+ SkRegion fDirty0Storage;
+ SkRegion fDirty1Storage;
+ int fWidth;
+ int fHeight;
+};
+
+#endif
+