summaryrefslogtreecommitdiffstats
path: root/skia/images/SkCreateRLEPixelRef.cpp
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
commitae2c20f398933a9e86c387dcc465ec0f71065ffc (patch)
treede668b1411e2ee0b4e49b6d8f8b68183134ac990 /skia/images/SkCreateRLEPixelRef.cpp
parent09911bf300f1a419907a9412154760efd0b7abc3 (diff)
downloadchromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.zip
chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.gz
chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.bz2
Add skia to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/images/SkCreateRLEPixelRef.cpp')
-rw-r--r--skia/images/SkCreateRLEPixelRef.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/skia/images/SkCreateRLEPixelRef.cpp b/skia/images/SkCreateRLEPixelRef.cpp
new file mode 100644
index 0000000..5756237
--- /dev/null
+++ b/skia/images/SkCreateRLEPixelRef.cpp
@@ -0,0 +1,120 @@
+#include "SkChunkAlloc.h"
+#include "SkPackBits.h"
+#include "SkBitmap.h"
+#include "SkPixelRef.h"
+
+class RLEPixelRef : public SkPixelRef {
+public:
+ RLEPixelRef(SkBitmap::RLEPixels* rlep, SkColorTable* ctable);
+ virtual ~RLEPixelRef();
+
+protected:
+ // overrides from SkPixelRef
+ virtual void* onLockPixels(SkColorTable**);
+ virtual void onUnlockPixels();
+
+private:
+ SkBitmap::RLEPixels* fRLEPixels;
+ SkColorTable* fCTable;
+};
+
+RLEPixelRef::RLEPixelRef(SkBitmap::RLEPixels* rlep, SkColorTable* ctable)
+ : SkPixelRef(NULL) {
+ fRLEPixels = rlep; // we now own this ptr
+ fCTable = ctable;
+ ctable->safeRef();
+}
+
+RLEPixelRef::~RLEPixelRef() {
+ SkDELETE(fRLEPixels);
+ fCTable->safeUnref();
+}
+
+void* RLEPixelRef::onLockPixels(SkColorTable** ct) {
+ *ct = fCTable;
+ return fRLEPixels;
+}
+
+void RLEPixelRef::onUnlockPixels() {
+ // nothing to do
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class ChunkRLEPixels : public SkBitmap::RLEPixels {
+public:
+ ChunkRLEPixels(int width, int height, size_t chunkSize)
+ : SkBitmap::RLEPixels(width, height), fStorage(chunkSize) {
+ }
+
+ SkChunkAlloc fStorage;
+};
+
+SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src);
+SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src) {
+
+ if (SkBitmap::kIndex8_Config != src.config() &&
+ SkBitmap::kA8_Config != src.config()) {
+ return NULL;
+ }
+
+ size_t maxPacked = SkPackBits::ComputeMaxSize8(src.width());
+
+ // estimate the rle size based on the original size
+ size_t size = src.getSize() >> 3;
+ if (size < maxPacked) {
+ size = maxPacked;
+ }
+
+ ChunkRLEPixels* rlePixels = SkNEW_ARGS(ChunkRLEPixels,
+ (src.width(), src.height(), size));
+
+ uint8_t* dstRow = NULL;
+ size_t free = 0;
+ size_t totalPacked = 0;
+
+ for (int y = 0; y < src.height(); y++) {
+ const uint8_t* srcRow = src.getAddr8(0, y);
+
+ if (free < maxPacked) {
+ dstRow = (uint8_t*)rlePixels->fStorage.allocThrow(size);
+ free = size;
+ }
+ size_t packedSize = SkPackBits::Pack8(srcRow, src.width(), dstRow);
+ SkASSERT(packedSize <= free);
+ rlePixels->setPackedAtY(y, dstRow);
+
+ dstRow += packedSize;
+ free -= packedSize;
+
+ totalPacked += packedSize;
+ }
+
+//#ifdef SK_DEBUG
+#if 0
+ // test
+ uint8_t* buffer = new uint8_t[src.width()];
+ for (int y = 0; y < src.height(); y++) {
+ const uint8_t* srcRow = src.getAddr8(0, y);
+ SkPackBits::Unpack8(buffer, 0, src.width(), rlePixels->packedAtY(y));
+ int n = memcmp(buffer, srcRow, src.width());
+ if (n) {
+ SkDebugf("----- memcmp returned %d on line %d\n", n, y);
+ }
+ SkASSERT(n == 0);
+ }
+ delete[] buffer;
+
+ size_t totalAlloc = src.height() * sizeof(uint8_t*) + totalPacked;
+
+ SkDebugf("--- RLE: orig [%d %d] %d, rle %d %d savings %g\n",
+ src.width(), src.height(), src.getSize(),
+ src.height() * sizeof(uint8_t*), totalPacked,
+ (float)totalAlloc / src.getSize());
+
+#endif
+
+ // transfer ownership of rlePixels to our pixelref
+ return SkNEW_ARGS(RLEPixelRef, (rlePixels, src.getColorTable()));
+}
+