Add the ability to dynamically generate keywords. Mark the Google engine as needing...
[chromium-blink-merge.git] / skia / images / SkCreateRLEPixelRef.cpp
blob575623749b3fd8e37be1c7d7a85636f972fe71dc
1 #include "SkChunkAlloc.h"
2 #include "SkPackBits.h"
3 #include "SkBitmap.h"
4 #include "SkPixelRef.h"
6 class RLEPixelRef : public SkPixelRef {
7 public:
8 RLEPixelRef(SkBitmap::RLEPixels* rlep, SkColorTable* ctable);
9 virtual ~RLEPixelRef();
11 protected:
12 // overrides from SkPixelRef
13 virtual void* onLockPixels(SkColorTable**);
14 virtual void onUnlockPixels();
16 private:
17 SkBitmap::RLEPixels* fRLEPixels;
18 SkColorTable* fCTable;
21 RLEPixelRef::RLEPixelRef(SkBitmap::RLEPixels* rlep, SkColorTable* ctable)
22 : SkPixelRef(NULL) {
23 fRLEPixels = rlep; // we now own this ptr
24 fCTable = ctable;
25 ctable->safeRef();
28 RLEPixelRef::~RLEPixelRef() {
29 SkDELETE(fRLEPixels);
30 fCTable->safeUnref();
33 void* RLEPixelRef::onLockPixels(SkColorTable** ct) {
34 *ct = fCTable;
35 return fRLEPixels;
38 void RLEPixelRef::onUnlockPixels() {
39 // nothing to do
42 /////////////////////////////////////////////////////////////////////////////
44 class ChunkRLEPixels : public SkBitmap::RLEPixels {
45 public:
46 ChunkRLEPixels(int width, int height, size_t chunkSize)
47 : SkBitmap::RLEPixels(width, height), fStorage(chunkSize) {
50 SkChunkAlloc fStorage;
53 SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src);
54 SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src) {
56 if (SkBitmap::kIndex8_Config != src.config() &&
57 SkBitmap::kA8_Config != src.config()) {
58 return NULL;
61 size_t maxPacked = SkPackBits::ComputeMaxSize8(src.width());
63 // estimate the rle size based on the original size
64 size_t size = src.getSize() >> 3;
65 if (size < maxPacked) {
66 size = maxPacked;
69 ChunkRLEPixels* rlePixels = SkNEW_ARGS(ChunkRLEPixels,
70 (src.width(), src.height(), size));
72 uint8_t* dstRow = NULL;
73 size_t free = 0;
74 size_t totalPacked = 0;
76 for (int y = 0; y < src.height(); y++) {
77 const uint8_t* srcRow = src.getAddr8(0, y);
79 if (free < maxPacked) {
80 dstRow = (uint8_t*)rlePixels->fStorage.allocThrow(size);
81 free = size;
83 size_t packedSize = SkPackBits::Pack8(srcRow, src.width(), dstRow);
84 SkASSERT(packedSize <= free);
85 rlePixels->setPackedAtY(y, dstRow);
87 dstRow += packedSize;
88 free -= packedSize;
90 totalPacked += packedSize;
93 //#ifdef SK_DEBUG
94 #if 0
95 // test
96 uint8_t* buffer = new uint8_t[src.width()];
97 for (int y = 0; y < src.height(); y++) {
98 const uint8_t* srcRow = src.getAddr8(0, y);
99 SkPackBits::Unpack8(buffer, 0, src.width(), rlePixels->packedAtY(y));
100 int n = memcmp(buffer, srcRow, src.width());
101 if (n) {
102 SkDebugf("----- memcmp returned %d on line %d\n", n, y);
104 SkASSERT(n == 0);
106 delete[] buffer;
108 size_t totalAlloc = src.height() * sizeof(uint8_t*) + totalPacked;
110 SkDebugf("--- RLE: orig [%d %d] %d, rle %d %d savings %g\n",
111 src.width(), src.height(), src.getSize(),
112 src.height() * sizeof(uint8_t*), totalPacked,
113 (float)totalAlloc / src.getSize());
115 #endif
117 // transfer ownership of rlePixels to our pixelref
118 return SkNEW_ARGS(RLEPixelRef, (rlePixels, src.getColorTable()));