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 
test_peekpixels(skiatest::Reporter * reporter)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
test_bigalloc(skiatest::Reporter * reporter)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 
test_allocpixels(skiatest::Reporter * reporter)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 
test_bigwidth(skiatest::Reporter * reporter)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  */
DEF_TEST(Bitmap,reporter)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  */
DEF_TEST(Bitmap_getColor_Swizzle,r)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(&copy, 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 
test_erasecolor_premul(skiatest::Reporter * reporter,SkColorType ct,SkColor input,SkColor expected)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  */
DEF_TEST(Bitmap_eraseColor_Premul,r)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