BitmapCopyTest.cpp revision 05b6b4d746867a9fb02e14edfe1bf3685abeb813
1215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "Test.h" 2215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "SkBitmap.h" 3215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "SkRect.h" 4215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 5215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstatic const char* boolStr(bool value) { 6215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed return value ? "true" : "false"; 7215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed} 8215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 9215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed// these are in the same order as the SkBitmap::Config enum 10215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstatic const char* gConfigName[] = { 11215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed "None", "A1", "A8", "Index8", "565", "4444", "8888", "RLE_Index8" 12215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed}; 13215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 14215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstatic void report_opaqueness(skiatest::Reporter* reporter, const SkBitmap& src, 15215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed const SkBitmap& dst) { 16215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkString str; 17215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed str.printf("src %s opaque:%d, dst %s opaque:%d", 18215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed gConfigName[src.config()], src.isOpaque(), 19215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed gConfigName[dst.config()], dst.isOpaque()); 20215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed reporter->reportFailed(str); 21215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed} 22215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 23215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstatic bool canHaveAlpha(SkBitmap::Config config) { 24215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed return config != SkBitmap::kRGB_565_Config; 25215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed} 26215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 27215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed// copyTo() should preserve isOpaque when it makes sense 28215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstatic void test_isOpaque(skiatest::Reporter* reporter, const SkBitmap& src, 29215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkBitmap::Config dstConfig) { 30215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkBitmap bitmap(src); 31215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkBitmap dst; 32215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 33215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // we need the lock so that we get a valid colorTable (when available) 34215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkAutoLockPixels alp(bitmap); 35215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkColorTable* ctable = bitmap.getColorTable(); 36215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed unsigned ctableFlags = ctable ? ctable->getFlags() : 0; 37215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 38215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (canHaveAlpha(bitmap.config()) && canHaveAlpha(dstConfig)) { 39215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed bitmap.setIsOpaque(false); 40215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (ctable) { 41215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed ctable->setFlags(ctableFlags & ~SkColorTable::kColorsAreOpaque_Flag); 42215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 43215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig)); 44215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, dst.config() == dstConfig); 45215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (bitmap.isOpaque() != dst.isOpaque()) { 46215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed report_opaqueness(reporter, bitmap, dst); 47215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 48215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 49215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 50215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed bitmap.setIsOpaque(true); 51215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (ctable) { 52215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed ctable->setFlags(ctableFlags | SkColorTable::kColorsAreOpaque_Flag); 53215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 54215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig)); 55215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, dst.config() == dstConfig); 56215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (bitmap.isOpaque() != dst.isOpaque()) { 57215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed report_opaqueness(reporter, bitmap, dst); 58215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 59215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 60215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (ctable) { 61215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed ctable->setFlags(ctableFlags); 62215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 63215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed} 64215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 6505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic void init_src(const SkBitmap& bitmap, const SkColorTable* ct) { 66215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkAutoLockPixels lock(bitmap); 67215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (bitmap.getPixels()) { 6805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (ct) { 6905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger sk_bzero(bitmap.getPixels(), bitmap.getSize()); 7005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } else { 7105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bitmap.eraseColor(SK_ColorWHITE); 7205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 73215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 74215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed} 75215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 76215473cea1702d8acc0316da3e5a9bf4ce0130efMike ReedSkColorTable* init_ctable() { 77215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkColor colors[] = { 78215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SK_ColorBLACK, SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE 79215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed }; 80215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed return new SkColorTable(colors, SK_ARRAY_COUNT(colors)); 81215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed} 82215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 83215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstruct Pair { 84215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkBitmap::Config fConfig; 85215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed const char* fValid; 86215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed}; 87215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 8805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// Utility functions for copyPixelsTo()/copyPixelsFrom() tests. 8905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// getPixel() 9005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// setPixel() 9105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// getSkConfigName() 9205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// struct Coordinates 9305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// reportCopyVerification() 9405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// writeCoordPixels() 9505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 9605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// Utility function to read the value of a given pixel in bm. All 9705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// values converted to uint32_t for simplification of comparisons. 9805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergeruint32_t getPixel(int x, int y, const SkBitmap& bm) { 9905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger uint32_t val = 0; 10005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger uint16_t val16; 10105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger uint8_t val8, shift; 10205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkAutoLockPixels lock(bm); 10305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const void* rawAddr = bm.getAddr(x,y); 10405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 10505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger switch (bm.getConfig()) { 10605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kARGB_8888_Config: 10705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memcpy(&val, rawAddr, sizeof(uint32_t)); 10805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 10905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kARGB_4444_Config: 11005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kRGB_565_Config: 11105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memcpy(&val16, rawAddr, sizeof(uint16_t)); 11205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger val = val16; 11305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 11405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kA8_Config: 11505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kIndex8_Config: 11605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memcpy(&val8, rawAddr, sizeof(uint8_t)); 11705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger val = val8; 11805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 11905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kA1_Config: 12005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memcpy(&val8, rawAddr, sizeof(uint8_t)); 12105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger shift = x % 8; 12205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger val = (val8 >> shift) & 0x1 ; 12305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 12405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger default: 12505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 12605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 12705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return val; 12805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 12905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 13005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// Utility function to set value of any pixel in bm. 13105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// bm.getConfig() specifies what format 'val' must be 13205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// converted to, but at present uint32_t can handle all formats. 13305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid setPixel(int x, int y, uint32_t val, SkBitmap& bm) { 13405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger uint16_t val16; 13505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger uint8_t val8, shift; 13605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkAutoLockPixels lock(bm); 13705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger void* rawAddr = bm.getAddr(x,y); 13805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 13905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger switch (bm.getConfig()) { 14005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kARGB_8888_Config: 14105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memcpy(rawAddr, &val, sizeof(uint32_t)); 14205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 14305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kARGB_4444_Config: 14405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kRGB_565_Config: 14505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger val16 = val & 0xFFFF; 14605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memcpy(rawAddr, &val16, sizeof(uint16_t)); 14705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 14805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kA8_Config: 14905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kIndex8_Config: 15005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger val8 = val & 0xFF; 15105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memcpy(rawAddr, &val8, sizeof(uint8_t)); 15205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 15305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kA1_Config: 15405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger shift = x % 8; // We assume we're in the right byte. 15505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memcpy(&val8, rawAddr, sizeof(uint8_t)); 15605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (val & 0x1) // Turn bit on. 15705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger val8 |= (0x1 << shift); 15805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger else // Turn bit off. 15905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger val8 &= ~(0x1 << shift); 16005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memcpy(rawAddr, &val8, sizeof(uint8_t)); 16105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 16205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger default: 16305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Ignore. 16405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 16505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 16605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 16705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 16805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// Utility to return string containing name of each format, to 16905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// simplify diagnostic output. 17005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerconst char* getSkConfigName(const SkBitmap& bm) { 17105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger switch (bm.getConfig()) { 17205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kNo_Config: return "SkBitmap::kNo_Config"; 17305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kA1_Config: return "SkBitmap::kA1_Config"; 17405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kA8_Config: return "SkBitmap::kA8_Config"; 17505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kIndex8_Config: return "SkBitmap::kIndex8_Config"; 17605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kRGB_565_Config: return "SkBitmap::kRGB_565_Config"; 17705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kARGB_4444_Config: return "SkBitmap::kARGB_4444_Config"; 17805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kARGB_8888_Config: return "SkBitmap::kARGB_8888_Config"; 17905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kRLE_Index8_Config: 18005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return "SkBitmap::kRLE_Index8_Config,"; 18105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger default: return "Unknown SkBitmap configuration."; 18205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 18305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 18405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 18505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// Helper struct to contain pixel locations, while avoiding need for STL. 18605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstruct Coordinates { 18705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 18805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const int length; 18905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkIPoint* const data; 19005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 19105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger explicit Coordinates(int _length): length(_length) 19205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger , data(new SkIPoint[length]) { } 19305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 19405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger ~Coordinates(){ 19505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger delete [] data; 19605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 19705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 19805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkIPoint* operator[](int i) const { 19905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Use with care, no bounds checking. 20005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return data + i; 20105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 20205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}; 20305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 20405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// A function to verify that two bitmaps contain the same pixel values 20505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// at all coordinates indicated by coords. Simplifies verification of 20605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// copied bitmaps. 20705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid reportCopyVerification(const SkBitmap& bm1, const SkBitmap& bm2, 20805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger Coordinates& coords, 20905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const char* msg, 21005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger skiatest::Reporter* reporter){ 21105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bool success = true; 21205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 21305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Confirm all pixels in the list match. 21405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger for (int i = 0; i < coords.length; ++i) 21505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger success = success && 21605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger (getPixel(coords[i]->fX, coords[i]->fY, bm1) == 21705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger getPixel(coords[i]->fX, coords[i]->fY, bm2)); 21805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 21905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (!success) { 22005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkString str; 22105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger str.printf("%s [config = %s]", 22205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger msg, getSkConfigName(bm1)); 22305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reporter->reportFailed(str); 22405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 22505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 22605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 22705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// Writes unique pixel values at locations specified by coords. 22805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid writeCoordPixels(SkBitmap& bm, const Coordinates& coords) { 22905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger for (int i = 0; i < coords.length; ++i) 23005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger setPixel(coords[i]->fX, coords[i]->fY, i, bm); 23105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 23205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 233215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstatic void TestBitmapCopy(skiatest::Reporter* reporter) { 234215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const Pair gPairs[] = { 235215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { SkBitmap::kNo_Config, "00000000" }, 236215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { SkBitmap::kA1_Config, "01000000" }, 237215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { SkBitmap::kA8_Config, "00101110" }, 238215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { SkBitmap::kIndex8_Config, "00111110" }, 239215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { SkBitmap::kRGB_565_Config, "00101110" }, 240215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { SkBitmap::kARGB_4444_Config, "00101110" }, 241215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { SkBitmap::kARGB_8888_Config, "00101110" }, 242215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed// TODO: create valid RLE bitmap to test with 243215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // { SkBitmap::kRLE_Index8_Config, "00101111" } 244215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed }; 245215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 24605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger static const bool isExtracted[] = { 24705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger false, true 24805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger }; 24905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 250215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed const int W = 20; 251215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed const int H = 33; 252215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 253215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { 254215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) { 255215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkBitmap src, dst; 256215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkColorTable* ct = NULL; 257215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 258215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed src.setConfig(gPairs[i].fConfig, W, H); 259215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (SkBitmap::kIndex8_Config == src.config() || 260215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkBitmap::kRLE_Index8_Config == src.config()) { 261215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed ct = init_ctable(); 262215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 263215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed src.allocPixels(ct); 264215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkSafeUnref(ct); 265215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 26605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger init_src(src, ct); 267215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed bool success = src.copyTo(&dst, gPairs[j].fConfig); 268215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed bool expected = gPairs[i].fValid[j] != '0'; 269215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (success != expected) { 270215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkString str; 271215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed str.printf("SkBitmap::copyTo from %s to %s. expected %s returned %s", 272215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed gConfigName[i], gConfigName[j], boolStr(expected), 273215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed boolStr(success)); 274215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed reporter->reportFailed(str); 275215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 27605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 277215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed bool canSucceed = src.canCopyTo(gPairs[j].fConfig); 278215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (success != canSucceed) { 279215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkString str; 280215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed str.printf("SkBitmap::copyTo from %s to %s. returned %s canCopyTo %s", 281215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed gConfigName[i], gConfigName[j], boolStr(success), 282215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed boolStr(canSucceed)); 283215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed reporter->reportFailed(str); 284215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 285215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 286215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (success) { 287215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, src.width() == dst.width()); 288215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, src.height() == dst.height()); 289215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, dst.config() == gPairs[j].fConfig); 290215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed test_isOpaque(reporter, src, dst.config()); 291215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (src.config() == dst.config()) { 292215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkAutoLockPixels srcLock(src); 293215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkAutoLockPixels dstLock(dst); 294215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, src.readyToDraw()); 295215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, dst.readyToDraw()); 296215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed const char* srcP = (const char*)src.getAddr(0, 0); 297215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed const char* dstP = (const char*)dst.getAddr(0, 0); 298215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, srcP != dstP); 299215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, !memcmp(srcP, dstP, 300215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed src.getSize())); 301215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 302215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // test extractSubset 303215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { 304215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkBitmap subset; 305215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkIRect r; 306215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed r.set(1, 1, 2, 2); 307215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (src.extractSubset(&subset, r)) { 308215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, subset.width() == 1); 309215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, subset.height() == 1); 310215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 311215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkBitmap copy; 312215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, 313215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed subset.copyTo(©, subset.config())); 314215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, copy.width() == 1); 315215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, copy.height() == 1); 316215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, copy.rowBytes() <= 4); 31705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 318215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkAutoLockPixels alp0(subset); 319215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkAutoLockPixels alp1(copy); 320215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // they should both have, or both not-have, a colortable 321215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed bool hasCT = subset.getColorTable() != NULL; 322215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, 323215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed (copy.getColorTable() != NULL) == hasCT); 324215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 325215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 326215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } else { 327215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // dst should be unchanged from its initial state 328215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, dst.config() == SkBitmap::kNo_Config); 329215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, dst.width() == 0); 330215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, dst.height() == 0); 331215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 33205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } // for (size_t j = ... 33305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 33405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Tests for getSafeSize(), getSafeSize64(), copyPixelsTo(), 33505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // copyPixelsFrom(). 33605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // 33705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger for (size_t copyCase = 0; copyCase < SK_ARRAY_COUNT(isExtracted); 33805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger ++copyCase) { 33905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test copying to/from external buffer. 34005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Note: the tests below have hard-coded values --- 34105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Please take care if modifying. 34205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (gPairs[i].fConfig != SkBitmap::kRLE_Index8_Config) { 34305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 34405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Tests for getSafeSize64(). 34505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test with a very large configuration without pixel buffer 34605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // attached. 34705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkBitmap tstSafeSize; 34805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger tstSafeSize.setConfig(gPairs[i].fConfig, 100000000U, 34905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 100000000U); 35005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger Sk64 safeSize = tstSafeSize.getSafeSize64(); 35105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (safeSize.isNeg()) { 35205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkString str; 35305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger str.printf("getSafeSize64() negative: %s", 35405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger getSkConfigName(tstSafeSize)); 35505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reporter->reportFailed(str); 35605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 35705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bool sizeFail = false; 35805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Compare against hand-computed values. 35905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger switch (gPairs[i].fConfig) { 36005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kNo_Config: 36105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 36205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 36305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kA1_Config: 36405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (safeSize.fHi != 0x470DE || 36505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger safeSize.fLo != 0x4DF82000) 36605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger sizeFail = true; 36705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 36805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 36905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kA8_Config: 37005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kIndex8_Config: 37105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (safeSize.fHi != 0x2386F2 || 37205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger safeSize.fLo != 0x6FC10000) 37305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger sizeFail = true; 37405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 37505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 37605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kRGB_565_Config: 37705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kARGB_4444_Config: 37805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (safeSize.fHi != 0x470DE4 || 37905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger safeSize.fLo != 0xDF820000) 38005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger sizeFail = true; 38105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 38205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 38305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kARGB_8888_Config: 38405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (safeSize.fHi != 0x8E1BC9 || 38505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger safeSize.fLo != 0xBF040000) 38605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger sizeFail = true; 38705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 38805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 38905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger case SkBitmap::kRLE_Index8_Config: 39005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 39105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 39205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger default: 39305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger break; 39405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 39505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (sizeFail) { 39605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkString str; 39705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger str.printf("getSafeSize64() wrong size: %s", 39805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger getSkConfigName(tstSafeSize)); 39905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reporter->reportFailed(str); 40005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 40105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 40205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger size_t subW, subH; 40305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Set sizes to be height = 2 to force the last row of the 40405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // source to be used, thus verifying correct operation if 40505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // the bitmap is an extracted subset. 40605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (gPairs[i].fConfig == SkBitmap::kA1_Config) { 40705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // If one-bit per pixel, use 9 pixels to force more than 40805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // one byte per row. 40905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subW = 9; 41005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subH = 2; 41105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } else { 41205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // All other configurations are at least one byte per pixel, 41305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // and different configs will test copying different numbers 41405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // of bytes. 41505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subW = subH = 2; 41605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 41705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 41805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Create bitmap to act as source for copies and subsets. 41905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkBitmap src, subset; 42005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkColorTable* ct = NULL; 42105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (isExtracted[copyCase]) { // A larger image to extract from. 42205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger src.setConfig(gPairs[i].fConfig, 2 * subW + 1, subH); 42305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } else // Tests expect a 2x2 bitmap, so make smaller. 42405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger src.setConfig(gPairs[i].fConfig, subW, subH); 42505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (SkBitmap::kIndex8_Config == src.config() || 42605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkBitmap::kRLE_Index8_Config == src.config()) { 42705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger ct = init_ctable(); 42805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 42905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 43005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger src.allocPixels(ct); 43105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkSafeUnref(ct); 43205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 43305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Either copy src or extract into 'subset', which is used 43405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // for subsequent calls to copyPixelsTo/From. 43505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bool srcReady = false; 43605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (isExtracted[copyCase]) { 43705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // The extractedSubset() test case allows us to test copy- 43805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // ing when src and dst mave possibly different strides. 43905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkIRect r; 44005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (gPairs[i].fConfig == SkBitmap::kA1_Config) 44105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // This config seems to need byte-alignment of 44205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // extracted subset bits. 44305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger r.set(0, 0, subW, subH); 44405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger else 44505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger r.set(1, 0, 1 + subW, subH); // 2x2 extracted bitmap 44605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 44705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger srcReady = src.extractSubset(&subset, r); 44805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } else { 44905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger srcReady = src.copyTo(&subset, src.getConfig()); 45005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 45105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 45205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Not all configurations will generate a valid 'subset'. 45305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (srcReady) { 45405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 45505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Allocate our target buffer 'buf' for all copies. 45605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // To simplify verifying correctness of copies attach 45705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // buf to a SkBitmap, but copies are done using the 45805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // raw buffer pointer. 45905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const uint32_t bufSize = subH * 46005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkBitmap::ComputeRowBytes(src.getConfig(), subW) * 2; 46105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger uint8_t* buf = new uint8_t[bufSize]; 46205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 46305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkBitmap bufBm; // Attach buf to this bitmap. 46405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bool successExpected; 46505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 46605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Set up values for each pixel being copied. 46705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger Coordinates coords(subW * subH); 46805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger for (size_t x = 0; x < subW; ++x) 46905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger for (size_t y = 0; y < subH; ++y) 47005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger { 47105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger int index = y * subW + x; 47205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkASSERT(index < coords.length); 47305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger coords[index]->fX = x; 47405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger coords[index]->fY = y; 47505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 47605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 47705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger writeCoordPixels(subset, coords); 47805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 47905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test #1 //////////////////////////////////////////// 48005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 48105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Before/after comparisons easier if we attach buf 48205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // to an appropriately configured SkBitmap. 48305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memset(buf, 0xFF, bufSize); 48405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Config with stride greater than src but that fits in buf. 48505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setConfig(gPairs[i].fConfig, subW, subH, 48605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkBitmap::ComputeRowBytes(subset.getConfig(), subW) 48705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger * 2); 48805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setPixels(buf); 48905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger successExpected = false; 49005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Then attempt to copy with a stride that is too large 49105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // to fit in the buffer. 49205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, 49305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.copyPixelsTo(buf, bufSize, bufBm.rowBytes() * 3) 49405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger == successExpected); 49505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 49605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (successExpected) 49705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reportCopyVerification(subset, bufBm, coords, 49805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger "copyPixelsTo(buf, bufSize, 1.5*maxRowBytes)", 49905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reporter); 50005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 50105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test #2 //////////////////////////////////////////// 50205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // This test should always succeed, but in the case 50305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // of extracted bitmaps only because we handle the 50405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // issue of getSafeSize(). Without getSafeSize() 50505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // buffer overrun/read would occur. 50605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memset(buf, 0xFF, bufSize); 50705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setConfig(gPairs[i].fConfig, subW, subH, 50805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.rowBytes()); 50905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setPixels(buf); 51005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger successExpected = subset.getSafeSize() <= bufSize; 51105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, 51205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.copyPixelsTo(buf, bufSize) == 51305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger successExpected); 51405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (successExpected) 51505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reportCopyVerification(subset, bufBm, coords, 51605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger "copyPixelsTo(buf, bufSize)", reporter); 51705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 51805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test #3 //////////////////////////////////////////// 51905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Copy with different stride between src and dst. 52005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memset(buf, 0xFF, bufSize); 52105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setConfig(gPairs[i].fConfig, subW, subH, 52205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.rowBytes()+1); 52305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setPixels(buf); 52405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger successExpected = true; // Should always work. 52505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, 52605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.copyPixelsTo(buf, bufSize, 52705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.rowBytes()+1) == successExpected); 52805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (successExpected) 52905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reportCopyVerification(subset, bufBm, coords, 53005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger "copyPixelsTo(buf, bufSize, rowBytes+1)", reporter); 53105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 53205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test #4 //////////////////////////////////////////// 53305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test copy with stride too small. 53405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memset(buf, 0xFF, bufSize); 53505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setConfig(gPairs[i].fConfig, subW, subH); 53605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setPixels(buf); 53705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger successExpected = false; 53805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Request copy with stride too small. 53905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, 54005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.copyPixelsTo(buf, bufSize, bufBm.rowBytes()-1) 54105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger == successExpected); 54205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (successExpected) 54305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reportCopyVerification(subset, bufBm, coords, 54405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger "copyPixelsTo(buf, bufSize, rowBytes()-1)", reporter); 54505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 54605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test #5 //////////////////////////////////////////// 54705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Tests the case where the source stride is too small 54805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // for the source configuration. 54905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger memset(buf, 0xFF, bufSize); 55005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setConfig(gPairs[i].fConfig, subW, subH); 55105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setPixels(buf); 55205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger writeCoordPixels(bufBm, coords); 55305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, 55405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.copyPixelsFrom(buf, bufSize, 1) == false); 55505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 55605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test #6 //////////////////////////////////////////// 55705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Tests basic copy from an external buffer to the bitmap. 55805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // If the bitmap is "extracted", this also tests the case 55905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // where the source stride is different from the dest. 56005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // stride. 56105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // We've made the buffer large enough to always succeed. 56205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setConfig(gPairs[i].fConfig, subW, subH); 56305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bufBm.setPixels(buf); 56405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger writeCoordPixels(bufBm, coords); 56505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, 56605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.copyPixelsFrom(buf, bufSize, bufBm.rowBytes()) == 56705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger true); 56805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reportCopyVerification(bufBm, subset, coords, 56905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger "copyPixelsFrom(buf, bufSize)", 57005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger reporter); 57105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 57205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Test #7 //////////////////////////////////////////// 57305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // Tests the case where the source buffer is too small 57405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger // for the transfer. 57505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, 57605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger subset.copyPixelsFrom(buf, 1, subset.rowBytes()) == 57705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger false); 57805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 57905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger delete [] buf; 58005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 58105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 58205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } // for (size_t copyCase ... 583215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 584215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed} 585215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 586215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "TestClassDef.h" 587215473cea1702d8acc0316da3e5a9bf4ce0130efMike ReedDEFINE_TESTCLASS("BitmapCopy", TestBitmapCopyClass, TestBitmapCopy) 588