Allow copying an Index8 bitmap when srcConfig and dstConfig are both

Index8.

Also, change the logic of SkBitmap.copyTo() to do memcpy() if srcConfig
and dstConfig are the same.


git-svn-id: http://skia.googlecode.com/svn/trunk@164 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
weita@google.com 2009-05-03 18:23:30 +00:00
parent 4226396806
commit f9ab99aaad
4 changed files with 130 additions and 90 deletions

View File

@ -485,7 +485,11 @@ private:
*/
class SkColorTable : public SkRefCnt {
public:
/** Constructs an empty color table (zero colors).
/** Makes a deep copy of colors.
*/
SkColorTable(const SkColorTable& src);
/** Preallocates the colortable to have 'count' colors, which
* are initially set to 0.
*/
explicit SkColorTable(int count);
explicit SkColorTable(SkFlattenableReadBuffer&);

View File

@ -683,25 +683,41 @@ bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
#include "SkPaint.h"
bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
if (NULL == dst || this->width() == 0 || this->height() == 0) {
if (NULL == dst || this->getConfig() == kNo_Config
|| this->width() == 0 || this->height() == 0) {
return false;
}
bool sameConfigs = (dstConfig == this->config());
switch (dstConfig) {
case kA8_Config:
case kARGB_4444_Config:
case kRGB_565_Config:
case kARGB_8888_Config:
break;
case kA1_Config:
case kIndex8_Config:
if (!sameConfigs) {
return false;
}
break;
default:
return false;
}
SkBitmap tmp;
// do not copy src if srcConfig == kA1_Config while dstConfig != kA1_Config
if (this->getConfig() == kA1_Config && !sameConfigs) {
return false;
}
SkBitmap tmp;
tmp.setConfig(dstConfig, this->width(), this->height());
// pass null for colortable, since we don't support Index8 config for dst
if (!tmp.allocPixels(alloc, NULL)) {
// allocate colortable if srcConfig == kIndex8_Config
SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
new SkColorTable(*this->getColorTable()) : NULL;
SkAutoUnref au(ctable);
if (!tmp.allocPixels(alloc, ctable)) {
return false;
}
@ -713,6 +729,12 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
return false;
}
/* do memcpy for the sameConfigs cases and
re-draw for the !sameConfigs cases
*/
if (sameConfigs) {
memcpy(tmp.getPixels(), this->getPixels(), this->getSize());
} else {
// if the src has alpha, we have to clear the dst first
if (!this->isOpaque()) {
tmp.eraseColor(0);
@ -723,6 +745,7 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
paint.setDither(true);
canvas.drawBitmap(*this, 0, 0, &paint);
}
dst->swap(tmp);
return true;

View File

@ -36,6 +36,18 @@ SkColorTable::SkColorTable(int count)
SkDEBUGCODE(f16BitCacheLockCount = 0;)
}
SkColorTable::SkColorTable(const SkColorTable& src) {
f16BitCache = NULL;
fFlags = src.fFlags;
int count = src.count();
fCount = SkToU16(count);
fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor));
memcpy(fColors, src.fColors, count * sizeof(SkPMColor));
SkDEBUGCODE(fColorLockCount = 0;)
SkDEBUGCODE(f16BitCacheLockCount = 0;)
}
SkColorTable::SkColorTable(const SkPMColor colors[], int count)
: f16BitCache(NULL), fFlags(0)
{

View File

@ -32,7 +32,7 @@ struct Pair {
static void TestBitmapCopy(skiatest::Reporter* reporter) {
static const Pair gPairs[] = {
{ SkBitmap::kNo_Config, "00000000" },
{ SkBitmap::kA1_Config, "01101110" },
{ SkBitmap::kA1_Config, "01000000" },
{ SkBitmap::kA8_Config, "00101110" },
{ SkBitmap::kIndex8_Config, "00111110" },
{ SkBitmap::kRGB_565_Config, "00101110" },
@ -70,6 +70,7 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
if (success) {
REPORTER_ASSERT(reporter, src.width() == dst.width());
REPORTER_ASSERT(reporter, src.height() == dst.height());
REPORTER_ASSERT(reporter, dst.config() == gPairs[j].fConfig);
if (src.config() == dst.config()) {
SkAutoLockPixels srcLock(src);
SkAutoLockPixels dstLock(dst);