1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkBitmap.h" 9 #include "SkMallocPixelRef.h" 10 #include "Test.h" 11 12 static void test_peekpixels(skiatest::Reporter* reporter) { 13 const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); 14 15 SkPixmap pmap; 16 SkBitmap bm; 17 18 // empty should return false 19 REPORTER_ASSERT(reporter, !bm.peekPixels(nullptr)); 20 REPORTER_ASSERT(reporter, !bm.peekPixels(&pmap)); 21 22 // no pixels should return false 23 bm.setInfo(SkImageInfo::MakeN32Premul(10, 10)); 24 REPORTER_ASSERT(reporter, !bm.peekPixels(nullptr)); 25 REPORTER_ASSERT(reporter, !bm.peekPixels(&pmap)); 26 27 // real pixels should return true 28 bm.allocPixels(info); 29 REPORTER_ASSERT(reporter, bm.peekPixels(nullptr)); 30 REPORTER_ASSERT(reporter, bm.peekPixels(&pmap)); 31 REPORTER_ASSERT(reporter, pmap.info() == bm.info()); 32 REPORTER_ASSERT(reporter, pmap.addr() == bm.getPixels()); 33 REPORTER_ASSERT(reporter, pmap.rowBytes() == bm.rowBytes()); 34 REPORTER_ASSERT(reporter, pmap.ctable() == bm.getColorTable()); 35 } 36 37 // https://code.google.com/p/chromium/issues/detail?id=446164 38 static void test_bigalloc(skiatest::Reporter* reporter) { 39 const int width = 0x40000001; 40 const int height = 0x00000096; 41 const SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 42 43 SkBitmap bm; 44 REPORTER_ASSERT(reporter, !bm.tryAllocPixels(info)); 45 46 SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, info.minRowBytes(), nullptr); 47 REPORTER_ASSERT(reporter, !pr); 48 } 49 50 static void test_allocpixels(skiatest::Reporter* reporter) { 51 const int width = 10; 52 const int height = 10; 53 const SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 54 const size_t explicitRowBytes = info.minRowBytes() + 24; 55 56 SkBitmap bm; 57 bm.setInfo(info); 58 REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes()); 59 bm.allocPixels(); 60 REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes()); 61 bm.reset(); 62 bm.allocPixels(info); 63 REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes()); 64 65 bm.setInfo(info, explicitRowBytes); 66 REPORTER_ASSERT(reporter, explicitRowBytes == bm.rowBytes()); 67 bm.allocPixels(); 68 REPORTER_ASSERT(reporter, explicitRowBytes == bm.rowBytes()); 69 bm.reset(); 70 bm.allocPixels(info, explicitRowBytes); 71 REPORTER_ASSERT(reporter, explicitRowBytes == bm.rowBytes()); 72 73 bm.reset(); 74 bm.setInfo(info, 0); 75 REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes()); 76 bm.reset(); 77 bm.allocPixels(info, 0); 78 REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes()); 79 80 bm.reset(); 81 bool success = bm.setInfo(info, info.minRowBytes() - 1); // invalid for 32bit 82 REPORTER_ASSERT(reporter, !success); 83 REPORTER_ASSERT(reporter, bm.isNull()); 84 } 85 86 static void test_bigwidth(skiatest::Reporter* reporter) { 87 SkBitmap bm; 88 int width = 1 << 29; // *4 will be the high-bit of 32bit int 89 90 SkImageInfo info = SkImageInfo::MakeA8(width, 1); 91 REPORTER_ASSERT(reporter, bm.setInfo(info)); 92 REPORTER_ASSERT(reporter, bm.setInfo(info.makeColorType(kRGB_565_SkColorType))); 93 94 // for a 4-byte config, this width will compute a rowbytes of 0x80000000, 95 // which does not fit in a int32_t. setConfig should detect this, and fail. 96 97 // TODO: perhaps skia can relax this, and only require that rowBytes fit 98 // in a uint32_t (or larger), but for now this is the constraint. 99 100 REPORTER_ASSERT(reporter, !bm.setInfo(info.makeColorType(kN32_SkColorType))); 101 } 102 103 /** 104 * This test contains basic sanity checks concerning bitmaps. 105 */ 106 DEF_TEST(Bitmap, reporter) { 107 // Zero-sized bitmaps are allowed 108 for (int width = 0; width < 2; ++width) { 109 for (int height = 0; height < 2; ++height) { 110 SkBitmap bm; 111 bool setConf = bm.setInfo(SkImageInfo::MakeN32Premul(width, height)); 112 REPORTER_ASSERT(reporter, setConf); 113 if (setConf) { 114 bm.allocPixels(); 115 } 116 REPORTER_ASSERT(reporter, SkToBool(width & height) != bm.empty()); 117 } 118 } 119 120 test_bigwidth(reporter); 121 test_allocpixels(reporter); 122 test_bigalloc(reporter); 123 test_peekpixels(reporter); 124 } 125 126 /** 127 * This test checks that getColor works for both swizzles. 128 */ 129 DEF_TEST(Bitmap_getColor_Swizzle, r) { 130 SkBitmap source; 131 source.allocN32Pixels(1,1); 132 source.eraseColor(SK_ColorRED); 133 SkColorType colorTypes[] = { 134 kRGBA_8888_SkColorType, 135 kBGRA_8888_SkColorType, 136 }; 137 for (SkColorType ct : colorTypes) { 138 SkBitmap copy; 139 if (!source.copyTo(©, ct)) { 140 ERRORF(r, "SkBitmap::copy failed %d", (int)ct); 141 continue; 142 } 143 SkAutoLockPixels autoLockPixels1(copy); 144 SkAutoLockPixels autoLockPixels2(source); 145 REPORTER_ASSERT(r, source.getColor(0, 0) == copy.getColor(0, 0)); 146 } 147 } 148 149 static void test_erasecolor_premul(skiatest::Reporter* reporter, SkColorType ct, SkColor input, 150 SkColor expected) { 151 SkBitmap bm; 152 bm.allocPixels(SkImageInfo::Make(1, 1, ct, kPremul_SkAlphaType)); 153 bm.eraseColor(input); 154 INFOF(reporter, "expected: %x actual: %x\n", expected, bm.getColor(0, 0)); 155 REPORTER_ASSERT(reporter, bm.getColor(0, 0) == expected); 156 } 157 158 /** 159 * This test checks that eraseColor premultiplies the color correctly. 160 */ 161 DEF_TEST(Bitmap_eraseColor_Premul, r) { 162 SkColor color = 0x80FF0080; 163 test_erasecolor_premul(r, kAlpha_8_SkColorType, color, 0x80000000); 164 test_erasecolor_premul(r, kRGB_565_SkColorType, color, 0xFF840042); 165 test_erasecolor_premul(r, kARGB_4444_SkColorType, color, 0x88FF0080); 166 test_erasecolor_premul(r, kRGBA_8888_SkColorType, color, color); 167 test_erasecolor_premul(r, kBGRA_8888_SkColorType, color, color); 168 } 169