2009-05-01 04:00:01 +00:00
|
|
|
#include "Test.h"
|
|
|
|
#include "SkBitmap.h"
|
2009-05-05 23:13:23 +00:00
|
|
|
#include "SkRect.h"
|
2009-05-01 04:00:01 +00:00
|
|
|
|
|
|
|
static const char* boolStr(bool value) {
|
|
|
|
return value ? "true" : "false";
|
|
|
|
}
|
|
|
|
|
|
|
|
// these are in the same order as the SkBitmap::Config enum
|
|
|
|
static const char* gConfigName[] = {
|
|
|
|
"None", "A1", "A8", "Index8", "565", "4444", "8888", "RLE_Index8"
|
|
|
|
};
|
|
|
|
|
2009-08-22 03:44:57 +00:00
|
|
|
static void report_opaqueness(skiatest::Reporter* reporter, const SkBitmap& src,
|
|
|
|
const SkBitmap& dst) {
|
|
|
|
SkString str;
|
|
|
|
str.printf("src %s opaque:%d, dst %s opaque:%d",
|
|
|
|
gConfigName[src.config()], src.isOpaque(),
|
|
|
|
gConfigName[dst.config()], dst.isOpaque());
|
|
|
|
reporter->reportFailed(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool canHaveAlpha(SkBitmap::Config config) {
|
|
|
|
return config != SkBitmap::kRGB_565_Config;
|
|
|
|
}
|
|
|
|
|
|
|
|
// copyTo() should preserve isOpaque when it makes sense
|
|
|
|
static void test_isOpaque(skiatest::Reporter* reporter, const SkBitmap& src,
|
|
|
|
SkBitmap::Config dstConfig) {
|
|
|
|
SkBitmap bitmap(src);
|
|
|
|
SkBitmap dst;
|
|
|
|
|
|
|
|
// we need the lock so that we get a valid colorTable (when available)
|
|
|
|
SkAutoLockPixels alp(bitmap);
|
|
|
|
SkColorTable* ctable = bitmap.getColorTable();
|
|
|
|
unsigned ctableFlags = ctable ? ctable->getFlags() : 0;
|
|
|
|
|
|
|
|
if (canHaveAlpha(bitmap.config()) && canHaveAlpha(dstConfig)) {
|
|
|
|
bitmap.setIsOpaque(false);
|
|
|
|
if (ctable) {
|
|
|
|
ctable->setFlags(ctableFlags & ~SkColorTable::kColorsAreOpaque_Flag);
|
|
|
|
}
|
|
|
|
REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig));
|
|
|
|
REPORTER_ASSERT(reporter, dst.config() == dstConfig);
|
|
|
|
if (bitmap.isOpaque() != dst.isOpaque()) {
|
|
|
|
report_opaqueness(reporter, bitmap, dst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bitmap.setIsOpaque(true);
|
|
|
|
if (ctable) {
|
|
|
|
ctable->setFlags(ctableFlags | SkColorTable::kColorsAreOpaque_Flag);
|
|
|
|
}
|
|
|
|
REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig));
|
|
|
|
REPORTER_ASSERT(reporter, dst.config() == dstConfig);
|
|
|
|
if (bitmap.isOpaque() != dst.isOpaque()) {
|
|
|
|
report_opaqueness(reporter, bitmap, dst);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ctable) {
|
|
|
|
ctable->setFlags(ctableFlags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-01 04:00:01 +00:00
|
|
|
static void init_src(const SkBitmap& bitmap) {
|
2009-05-03 18:23:30 +00:00
|
|
|
SkAutoLockPixels lock(bitmap);
|
2009-05-01 04:00:01 +00:00
|
|
|
if (bitmap.getPixels()) {
|
|
|
|
memset(bitmap.getPixels(), 4, bitmap.getSize());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SkColorTable* init_ctable() {
|
|
|
|
static const SkColor colors[] = {
|
|
|
|
SK_ColorBLACK, SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE
|
|
|
|
};
|
|
|
|
return new SkColorTable(colors, SK_ARRAY_COUNT(colors));
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Pair {
|
|
|
|
SkBitmap::Config fConfig;
|
|
|
|
const char* fValid;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void TestBitmapCopy(skiatest::Reporter* reporter) {
|
|
|
|
static const Pair gPairs[] = {
|
|
|
|
{ SkBitmap::kNo_Config, "00000000" },
|
2009-05-03 18:23:30 +00:00
|
|
|
{ SkBitmap::kA1_Config, "01000000" },
|
2009-05-01 04:00:01 +00:00
|
|
|
{ SkBitmap::kA8_Config, "00101110" },
|
|
|
|
{ SkBitmap::kIndex8_Config, "00111110" },
|
|
|
|
{ SkBitmap::kRGB_565_Config, "00101110" },
|
|
|
|
{ SkBitmap::kARGB_4444_Config, "00101110" },
|
|
|
|
{ SkBitmap::kARGB_8888_Config, "00101110" },
|
2009-05-06 17:44:34 +00:00
|
|
|
// TODO: create valid RLE bitmap to test with
|
|
|
|
// { SkBitmap::kRLE_Index8_Config, "00101111" }
|
2009-05-01 04:00:01 +00:00
|
|
|
};
|
2009-05-03 18:23:30 +00:00
|
|
|
|
2009-05-01 04:00:01 +00:00
|
|
|
const int W = 20;
|
|
|
|
const int H = 33;
|
2009-05-03 18:23:30 +00:00
|
|
|
|
2009-05-01 04:00:01 +00:00
|
|
|
for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
|
|
|
|
for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) {
|
|
|
|
SkBitmap src, dst;
|
|
|
|
SkColorTable* ct = NULL;
|
2009-05-03 18:23:30 +00:00
|
|
|
|
2009-05-01 04:00:01 +00:00
|
|
|
src.setConfig(gPairs[i].fConfig, W, H);
|
2009-05-06 17:44:34 +00:00
|
|
|
if (SkBitmap::kIndex8_Config == src.config() ||
|
|
|
|
SkBitmap::kRLE_Index8_Config == src.config()) {
|
2009-05-01 04:00:01 +00:00
|
|
|
ct = init_ctable();
|
|
|
|
}
|
|
|
|
src.allocPixels(ct);
|
|
|
|
ct->safeRef();
|
|
|
|
|
|
|
|
init_src(src);
|
|
|
|
bool success = src.copyTo(&dst, gPairs[j].fConfig);
|
|
|
|
bool expected = gPairs[i].fValid[j] != '0';
|
|
|
|
if (success != expected) {
|
|
|
|
SkString str;
|
|
|
|
str.printf("SkBitmap::copyTo from %s to %s. expected %s returned %s",
|
|
|
|
gConfigName[i], gConfigName[j], boolStr(expected),
|
|
|
|
boolStr(success));
|
|
|
|
reporter->reportFailed(str);
|
|
|
|
}
|
2009-05-06 17:44:34 +00:00
|
|
|
|
|
|
|
bool canSucceed = src.canCopyTo(gPairs[j].fConfig);
|
|
|
|
if (success != canSucceed) {
|
|
|
|
SkString str;
|
|
|
|
str.printf("SkBitmap::copyTo from %s to %s. returned %s canCopyTo %s",
|
|
|
|
gConfigName[i], gConfigName[j], boolStr(success),
|
|
|
|
boolStr(canSucceed));
|
|
|
|
reporter->reportFailed(str);
|
|
|
|
}
|
2009-05-03 18:23:30 +00:00
|
|
|
|
2009-05-01 04:00:01 +00:00
|
|
|
if (success) {
|
|
|
|
REPORTER_ASSERT(reporter, src.width() == dst.width());
|
|
|
|
REPORTER_ASSERT(reporter, src.height() == dst.height());
|
2009-05-03 18:23:30 +00:00
|
|
|
REPORTER_ASSERT(reporter, dst.config() == gPairs[j].fConfig);
|
2009-08-22 03:44:57 +00:00
|
|
|
test_isOpaque(reporter, src, dst.config());
|
2009-05-01 04:00:01 +00:00
|
|
|
if (src.config() == dst.config()) {
|
2009-05-03 18:23:30 +00:00
|
|
|
SkAutoLockPixels srcLock(src);
|
2009-05-01 04:00:01 +00:00
|
|
|
SkAutoLockPixels dstLock(dst);
|
|
|
|
REPORTER_ASSERT(reporter, src.readyToDraw());
|
|
|
|
REPORTER_ASSERT(reporter, dst.readyToDraw());
|
|
|
|
const char* srcP = (const char*)src.getAddr(0, 0);
|
|
|
|
const char* dstP = (const char*)dst.getAddr(0, 0);
|
|
|
|
REPORTER_ASSERT(reporter, srcP != dstP);
|
|
|
|
REPORTER_ASSERT(reporter, !memcmp(srcP, dstP,
|
|
|
|
src.getSize()));
|
|
|
|
}
|
2009-05-05 23:13:23 +00:00
|
|
|
// test extractSubset
|
|
|
|
{
|
|
|
|
SkBitmap subset;
|
|
|
|
SkIRect r;
|
|
|
|
r.set(1, 1, 2, 2);
|
|
|
|
if (src.extractSubset(&subset, r)) {
|
|
|
|
REPORTER_ASSERT(reporter, subset.width() == 1);
|
|
|
|
REPORTER_ASSERT(reporter, subset.height() == 1);
|
|
|
|
|
|
|
|
SkBitmap copy;
|
|
|
|
REPORTER_ASSERT(reporter,
|
|
|
|
subset.copyTo(©, subset.config()));
|
|
|
|
REPORTER_ASSERT(reporter, copy.width() == 1);
|
|
|
|
REPORTER_ASSERT(reporter, copy.height() == 1);
|
|
|
|
REPORTER_ASSERT(reporter, copy.rowBytes() <= 4);
|
|
|
|
|
|
|
|
SkAutoLockPixels alp0(subset);
|
|
|
|
SkAutoLockPixels alp1(copy);
|
|
|
|
// they should both have, or both not-have, a colortable
|
|
|
|
bool hasCT = subset.getColorTable() != NULL;
|
|
|
|
REPORTER_ASSERT(reporter,
|
|
|
|
(copy.getColorTable() != NULL) == hasCT);
|
|
|
|
}
|
|
|
|
}
|
2009-05-01 04:00:01 +00:00
|
|
|
} else {
|
|
|
|
// dst should be unchanged from its initial state
|
|
|
|
REPORTER_ASSERT(reporter, dst.config() == SkBitmap::kNo_Config);
|
|
|
|
REPORTER_ASSERT(reporter, dst.width() == 0);
|
|
|
|
REPORTER_ASSERT(reporter, dst.height() == 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "TestClassDef.h"
|
|
|
|
DEFINE_TESTCLASS("BitmapCopy", TestBitmapCopyClass, TestBitmapCopy)
|