OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "Test.h" | 8 #include "Test.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkRect.h" | 10 #include "SkRect.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 gConfigName[src.config()], src.isOpaque(), | 25 gConfigName[src.config()], src.isOpaque(), |
26 gConfigName[dst.config()], dst.isOpaque()); | 26 gConfigName[dst.config()], dst.isOpaque()); |
27 reporter->reportFailed(str); | 27 reporter->reportFailed(str); |
28 } | 28 } |
29 | 29 |
30 static bool canHaveAlpha(SkBitmap::Config config) { | 30 static bool canHaveAlpha(SkBitmap::Config config) { |
31 return config != SkBitmap::kRGB_565_Config; | 31 return config != SkBitmap::kRGB_565_Config; |
32 } | 32 } |
33 | 33 |
34 // copyTo() should preserve isOpaque when it makes sense | 34 // copyTo() should preserve isOpaque when it makes sense |
35 static void test_isOpaque(skiatest::Reporter* reporter, const SkBitmap& src, | 35 static void test_isOpaque(skiatest::Reporter* reporter, |
| 36 const SkBitmap& srcOpaque, const SkBitmap& srcPremul, |
36 SkBitmap::Config dstConfig) { | 37 SkBitmap::Config dstConfig) { |
37 SkBitmap bitmap(src); | |
38 SkBitmap dst; | 38 SkBitmap dst; |
39 | 39 |
40 // we need the lock so that we get a valid colorTable (when available) | 40 if (canHaveAlpha(srcPremul.config()) && canHaveAlpha(dstConfig)) { |
41 SkAutoLockPixels alp(bitmap); | 41 REPORTER_ASSERT(reporter, srcPremul.copyTo(&dst, dstConfig)); |
42 SkColorTable* ctable = bitmap.getColorTable(); | |
43 unsigned ctableFlags = ctable ? ctable->getFlags() : 0; | |
44 | |
45 if (canHaveAlpha(bitmap.config()) && canHaveAlpha(dstConfig)) { | |
46 bitmap.setIsOpaque(false); | |
47 if (ctable) { | |
48 ctable->setFlags(ctableFlags & ~SkColorTable::kColorsAreOpaque_Flag)
; | |
49 } | |
50 REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig)); | |
51 REPORTER_ASSERT(reporter, dst.config() == dstConfig); | 42 REPORTER_ASSERT(reporter, dst.config() == dstConfig); |
52 if (bitmap.isOpaque() != dst.isOpaque()) { | 43 if (srcPremul.isOpaque() != dst.isOpaque()) { |
53 report_opaqueness(reporter, bitmap, dst); | 44 report_opaqueness(reporter, srcPremul, dst); |
54 } | 45 } |
55 } | 46 } |
56 | 47 |
57 bitmap.setIsOpaque(true); | 48 REPORTER_ASSERT(reporter, srcOpaque.copyTo(&dst, dstConfig)); |
58 if (ctable) { | |
59 ctable->setFlags(ctableFlags | SkColorTable::kColorsAreOpaque_Flag); | |
60 } | |
61 REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig)); | |
62 REPORTER_ASSERT(reporter, dst.config() == dstConfig); | 49 REPORTER_ASSERT(reporter, dst.config() == dstConfig); |
63 if (bitmap.isOpaque() != dst.isOpaque()) { | 50 if (srcOpaque.isOpaque() != dst.isOpaque()) { |
64 report_opaqueness(reporter, bitmap, dst); | 51 report_opaqueness(reporter, srcOpaque, dst); |
65 } | |
66 | |
67 if (ctable) { | |
68 ctable->setFlags(ctableFlags); | |
69 } | 52 } |
70 } | 53 } |
71 | 54 |
72 static void init_src(const SkBitmap& bitmap, const SkColorTable* ct) { | 55 static void init_src(const SkBitmap& bitmap) { |
73 SkAutoLockPixels lock(bitmap); | 56 SkAutoLockPixels lock(bitmap); |
74 if (bitmap.getPixels()) { | 57 if (bitmap.getPixels()) { |
75 if (ct) { | 58 if (bitmap.getColorTable()) { |
76 sk_bzero(bitmap.getPixels(), bitmap.getSize()); | 59 sk_bzero(bitmap.getPixels(), bitmap.getSize()); |
77 } else { | 60 } else { |
78 bitmap.eraseColor(SK_ColorWHITE); | 61 bitmap.eraseColor(SK_ColorWHITE); |
79 } | 62 } |
80 } | 63 } |
81 } | 64 } |
82 | 65 |
83 static SkColorTable* init_ctable() { | 66 static SkColorTable* init_ctable(SkAlphaType alphaType) { |
84 static const SkColor colors[] = { | 67 static const SkColor colors[] = { |
85 SK_ColorBLACK, SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE | 68 SK_ColorBLACK, SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE |
86 }; | 69 }; |
87 return new SkColorTable(colors, SK_ARRAY_COUNT(colors)); | 70 return new SkColorTable(colors, SK_ARRAY_COUNT(colors), alphaType); |
88 } | 71 } |
89 | 72 |
90 struct Pair { | 73 struct Pair { |
91 SkBitmap::Config fConfig; | 74 SkBitmap::Config fConfig; |
92 const char* fValid; | 75 const char* fValid; |
93 }; | 76 }; |
94 | 77 |
95 // Utility functions for copyPixelsTo()/copyPixelsFrom() tests. | 78 // Utility functions for copyPixelsTo()/copyPixelsFrom() tests. |
96 // getPixel() | 79 // getPixel() |
97 // setPixel() | 80 // setPixel() |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 | 232 |
250 static const bool isExtracted[] = { | 233 static const bool isExtracted[] = { |
251 false, true | 234 false, true |
252 }; | 235 }; |
253 | 236 |
254 const int W = 20; | 237 const int W = 20; |
255 const int H = 33; | 238 const int H = 33; |
256 | 239 |
257 for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { | 240 for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { |
258 for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) { | 241 for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) { |
259 SkBitmap src, dst; | 242 SkBitmap srcOpaque, srcPremul, dst; |
260 SkColorTable* ct = NULL; | 243 |
| 244 { |
| 245 SkColorTable* ctOpaque = NULL; |
| 246 SkColorTable* ctPremul = NULL; |
261 | 247 |
262 src.setConfig(gPairs[i].fConfig, W, H); | 248 srcOpaque.setConfig(gPairs[i].fConfig, W, H); |
263 if (SkBitmap::kIndex8_Config == src.config()) { | 249 srcPremul.setConfig(gPairs[i].fConfig, W, H); |
264 ct = init_ctable(); | 250 if (SkBitmap::kIndex8_Config == gPairs[i].fConfig) { |
| 251 ctOpaque = init_ctable(kOpaque_SkAlphaType); |
| 252 ctPremul = init_ctable(kPremul_SkAlphaType); |
| 253 } |
| 254 srcOpaque.allocPixels(ctOpaque); |
| 255 srcPremul.allocPixels(ctPremul); |
| 256 SkSafeUnref(ctOpaque); |
| 257 SkSafeUnref(ctPremul); |
| 258 |
| 259 srcOpaque.setIsOpaque(true); |
| 260 srcPremul.setIsOpaque(false); |
265 } | 261 } |
266 src.allocPixels(ct); | 262 init_src(srcOpaque); |
267 SkSafeUnref(ct); | 263 init_src(srcPremul); |
268 | 264 |
269 init_src(src, ct); | 265 bool success = srcPremul.copyTo(&dst, gPairs[j].fConfig); |
270 bool success = src.copyTo(&dst, gPairs[j].fConfig); | |
271 bool expected = gPairs[i].fValid[j] != '0'; | 266 bool expected = gPairs[i].fValid[j] != '0'; |
272 if (success != expected) { | 267 if (success != expected) { |
273 SkString str; | 268 SkString str; |
274 str.printf("SkBitmap::copyTo from %s to %s. expected %s returned
%s", | 269 str.printf("SkBitmap::copyTo from %s to %s. expected %s returned
%s", |
275 gConfigName[i], gConfigName[j], boolStr(expected), | 270 gConfigName[i], gConfigName[j], boolStr(expected), |
276 boolStr(success)); | 271 boolStr(success)); |
277 reporter->reportFailed(str); | 272 reporter->reportFailed(str); |
278 } | 273 } |
279 | 274 |
280 bool canSucceed = src.canCopyTo(gPairs[j].fConfig); | 275 bool canSucceed = srcPremul.canCopyTo(gPairs[j].fConfig); |
281 if (success != canSucceed) { | 276 if (success != canSucceed) { |
282 SkString str; | 277 SkString str; |
283 str.printf("SkBitmap::copyTo from %s to %s. returned %s canCopyT
o %s", | 278 str.printf("SkBitmap::copyTo from %s to %s. returned %s canCopyT
o %s", |
284 gConfigName[i], gConfigName[j], boolStr(success), | 279 gConfigName[i], gConfigName[j], boolStr(success), |
285 boolStr(canSucceed)); | 280 boolStr(canSucceed)); |
286 reporter->reportFailed(str); | 281 reporter->reportFailed(str); |
287 } | 282 } |
288 | 283 |
289 if (success) { | 284 if (success) { |
290 REPORTER_ASSERT(reporter, src.width() == dst.width()); | 285 REPORTER_ASSERT(reporter, srcPremul.width() == dst.width()); |
291 REPORTER_ASSERT(reporter, src.height() == dst.height()); | 286 REPORTER_ASSERT(reporter, srcPremul.height() == dst.height()); |
292 REPORTER_ASSERT(reporter, dst.config() == gPairs[j].fConfig); | 287 REPORTER_ASSERT(reporter, dst.config() == gPairs[j].fConfig); |
293 test_isOpaque(reporter, src, dst.config()); | 288 test_isOpaque(reporter, srcOpaque, srcPremul, dst.config()); |
294 if (src.config() == dst.config()) { | 289 if (srcPremul.config() == dst.config()) { |
295 SkAutoLockPixels srcLock(src); | 290 SkAutoLockPixels srcLock(srcPremul); |
296 SkAutoLockPixels dstLock(dst); | 291 SkAutoLockPixels dstLock(dst); |
297 REPORTER_ASSERT(reporter, src.readyToDraw()); | 292 REPORTER_ASSERT(reporter, srcPremul.readyToDraw()); |
298 REPORTER_ASSERT(reporter, dst.readyToDraw()); | 293 REPORTER_ASSERT(reporter, dst.readyToDraw()); |
299 const char* srcP = (const char*)src.getAddr(0, 0); | 294 const char* srcP = (const char*)srcPremul.getAddr(0, 0); |
300 const char* dstP = (const char*)dst.getAddr(0, 0); | 295 const char* dstP = (const char*)dst.getAddr(0, 0); |
301 REPORTER_ASSERT(reporter, srcP != dstP); | 296 REPORTER_ASSERT(reporter, srcP != dstP); |
302 REPORTER_ASSERT(reporter, !memcmp(srcP, dstP, | 297 REPORTER_ASSERT(reporter, !memcmp(srcP, dstP, |
303 src.getSize())); | 298 srcPremul.getSize())); |
304 REPORTER_ASSERT(reporter, src.getGenerationID() == dst.getGe
nerationID()); | 299 REPORTER_ASSERT(reporter, srcPremul.getGenerationID() == dst
.getGenerationID()); |
305 } else { | 300 } else { |
306 REPORTER_ASSERT(reporter, src.getGenerationID() != dst.getGe
nerationID()); | 301 REPORTER_ASSERT(reporter, srcPremul.getGenerationID() != dst
.getGenerationID()); |
307 } | 302 } |
308 // test extractSubset | 303 // test extractSubset |
309 { | 304 { |
310 SkBitmap bitmap(src); | 305 SkBitmap bitmap(srcOpaque); |
311 SkBitmap subset; | 306 SkBitmap subset; |
312 SkIRect r; | 307 SkIRect r; |
313 r.set(1, 1, 2, 2); | 308 r.set(1, 1, 2, 2); |
314 bitmap.setIsOpaque(true); | |
315 bitmap.setIsVolatile(true); | 309 bitmap.setIsVolatile(true); |
316 if (bitmap.extractSubset(&subset, r)) { | 310 if (bitmap.extractSubset(&subset, r)) { |
317 REPORTER_ASSERT(reporter, subset.width() == 1); | 311 REPORTER_ASSERT(reporter, subset.width() == 1); |
318 REPORTER_ASSERT(reporter, subset.height() == 1); | 312 REPORTER_ASSERT(reporter, subset.height() == 1); |
319 REPORTER_ASSERT(reporter, | 313 REPORTER_ASSERT(reporter, |
320 subset.isOpaque() == bitmap.isOpaque()); | 314 subset.isOpaque() == bitmap.isOpaque()); |
321 REPORTER_ASSERT(reporter, | 315 REPORTER_ASSERT(reporter, |
322 subset.isVolatile() == true); | 316 subset.isVolatile() == true); |
323 | 317 |
324 SkBitmap copy; | 318 SkBitmap copy; |
325 REPORTER_ASSERT(reporter, | 319 REPORTER_ASSERT(reporter, |
326 subset.copyTo(©, subset.config())); | 320 subset.copyTo(©, subset.config())); |
327 REPORTER_ASSERT(reporter, copy.width() == 1); | 321 REPORTER_ASSERT(reporter, copy.width() == 1); |
328 REPORTER_ASSERT(reporter, copy.height() == 1); | 322 REPORTER_ASSERT(reporter, copy.height() == 1); |
329 REPORTER_ASSERT(reporter, copy.rowBytes() <= 4); | 323 REPORTER_ASSERT(reporter, copy.rowBytes() <= 4); |
330 | 324 |
331 SkAutoLockPixels alp0(subset); | 325 SkAutoLockPixels alp0(subset); |
332 SkAutoLockPixels alp1(copy); | 326 SkAutoLockPixels alp1(copy); |
333 // they should both have, or both not-have, a colortable | 327 // they should both have, or both not-have, a colortable |
334 bool hasCT = subset.getColorTable() != NULL; | 328 bool hasCT = subset.getColorTable() != NULL; |
335 REPORTER_ASSERT(reporter, | 329 REPORTER_ASSERT(reporter, |
336 (copy.getColorTable() != NULL) == hasCT); | 330 (copy.getColorTable() != NULL) == hasCT); |
337 } | 331 } |
338 bitmap.setIsOpaque(false); | 332 |
| 333 bitmap = srcPremul; |
339 bitmap.setIsVolatile(false); | 334 bitmap.setIsVolatile(false); |
340 if (bitmap.extractSubset(&subset, r)) { | 335 if (bitmap.extractSubset(&subset, r)) { |
341 REPORTER_ASSERT(reporter, | 336 REPORTER_ASSERT(reporter, |
342 subset.isOpaque() == bitmap.isOpaque()); | 337 subset.isOpaque() == bitmap.isOpaque()); |
343 REPORTER_ASSERT(reporter, | 338 REPORTER_ASSERT(reporter, |
344 subset.isVolatile() == false); | 339 subset.isVolatile() == false); |
345 } | 340 } |
346 } | 341 } |
347 } else { | 342 } else { |
348 // dst should be unchanged from its initial state | 343 // dst should be unchanged from its initial state |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 | 429 |
435 // Create bitmap to act as source for copies and subsets. | 430 // Create bitmap to act as source for copies and subsets. |
436 SkBitmap src, subset; | 431 SkBitmap src, subset; |
437 SkColorTable* ct = NULL; | 432 SkColorTable* ct = NULL; |
438 if (isExtracted[copyCase]) { // A larger image to extract from. | 433 if (isExtracted[copyCase]) { // A larger image to extract from. |
439 src.setConfig(gPairs[i].fConfig, 2 * subW + 1, subH); | 434 src.setConfig(gPairs[i].fConfig, 2 * subW + 1, subH); |
440 } else { // Tests expect a 2x2 bitmap, so make smaller. | 435 } else { // Tests expect a 2x2 bitmap, so make smaller. |
441 src.setConfig(gPairs[i].fConfig, subW, subH); | 436 src.setConfig(gPairs[i].fConfig, subW, subH); |
442 } | 437 } |
443 if (SkBitmap::kIndex8_Config == src.config()) { | 438 if (SkBitmap::kIndex8_Config == src.config()) { |
444 ct = init_ctable(); | 439 ct = init_ctable(kPremul_SkAlphaType); |
445 } | 440 } |
446 | 441 |
447 src.allocPixels(ct); | 442 src.allocPixels(ct); |
448 SkSafeUnref(ct); | 443 SkSafeUnref(ct); |
449 | 444 |
450 // Either copy src or extract into 'subset', which is used | 445 // Either copy src or extract into 'subset', which is used |
451 // for subsequent calls to copyPixelsTo/From. | 446 // for subsequent calls to copyPixelsTo/From. |
452 bool srcReady = false; | 447 bool srcReady = false; |
453 if (isExtracted[copyCase]) { | 448 if (isExtracted[copyCase]) { |
454 // The extractedSubset() test case allows us to test copy- | 449 // The extractedSubset() test case allows us to test copy- |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 false); | 591 false); |
597 | 592 |
598 #endif | 593 #endif |
599 } | 594 } |
600 } // for (size_t copyCase ... | 595 } // for (size_t copyCase ... |
601 } | 596 } |
602 } | 597 } |
603 | 598 |
604 #include "TestClassDef.h" | 599 #include "TestClassDef.h" |
605 DEFINE_TESTCLASS("BitmapCopy", TestBitmapCopyClass, TestBitmapCopy) | 600 DEFINE_TESTCLASS("BitmapCopy", TestBitmapCopyClass, TestBitmapCopy) |
OLD | NEW |