1 #include "SkChunkAlloc.h"
2 #include "SkPackBits.h"
4 #include "SkPixelRef.h"
6 class RLEPixelRef
: public SkPixelRef
{
8 RLEPixelRef(SkBitmap::RLEPixels
* rlep
, SkColorTable
* ctable
);
9 virtual ~RLEPixelRef();
12 // overrides from SkPixelRef
13 virtual void* onLockPixels(SkColorTable
**);
14 virtual void onUnlockPixels();
17 SkBitmap::RLEPixels
* fRLEPixels
;
18 SkColorTable
* fCTable
;
21 RLEPixelRef::RLEPixelRef(SkBitmap::RLEPixels
* rlep
, SkColorTable
* ctable
)
23 fRLEPixels
= rlep
; // we now own this ptr
28 RLEPixelRef::~RLEPixelRef() {
33 void* RLEPixelRef::onLockPixels(SkColorTable
** ct
) {
38 void RLEPixelRef::onUnlockPixels() {
42 /////////////////////////////////////////////////////////////////////////////
44 class ChunkRLEPixels
: public SkBitmap::RLEPixels
{
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()) {
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
) {
69 ChunkRLEPixels
* rlePixels
= SkNEW_ARGS(ChunkRLEPixels
,
70 (src
.width(), src
.height(), size
));
72 uint8_t* dstRow
= NULL
;
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
);
83 size_t packedSize
= SkPackBits::Pack8(srcRow
, src
.width(), dstRow
);
84 SkASSERT(packedSize
<= free
);
85 rlePixels
->setPackedAtY(y
, dstRow
);
90 totalPacked
+= packedSize
;
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());
102 SkDebugf("----- memcmp returned %d on line %d\n", n
, y
);
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());
117 // transfer ownership of rlePixels to our pixelref
118 return SkNEW_ARGS(RLEPixelRef
, (rlePixels
, src
.getColorTable()));