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