1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.graphics;
18
19import android.test.suitebuilder.annotation.SmallTest;
20import junit.framework.TestCase;
21
22
23public class BitmapTest extends TestCase {
24
25    @SmallTest
26    public void testBasic() throws Exception {
27        Bitmap bm1 = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888);
28        Bitmap bm2 = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
29        Bitmap bm3 = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_4444);
30
31        assertTrue("mutability", bm1.isMutable());
32        assertTrue("mutability", bm2.isMutable());
33        assertTrue("mutability", bm3.isMutable());
34
35        assertEquals("width", 100, bm1.getWidth());
36        assertEquals("width", 100, bm2.getWidth());
37        assertEquals("width", 100, bm3.getWidth());
38
39        assertEquals("rowbytes", 400, bm1.getRowBytes());
40        assertEquals("rowbytes", 200, bm2.getRowBytes());
41        assertEquals("rowbytes", 200, bm3.getRowBytes());
42
43        assertEquals("byteCount", 80000, bm1.getByteCount());
44        assertEquals("byteCount", 40000, bm2.getByteCount());
45        assertEquals("byteCount", 40000, bm3.getByteCount());
46
47        assertEquals("height", 200, bm1.getHeight());
48        assertEquals("height", 200, bm2.getHeight());
49        assertEquals("height", 200, bm3.getHeight());
50
51        assertTrue("hasAlpha", bm1.hasAlpha());
52        assertFalse("hasAlpha", bm2.hasAlpha());
53        assertTrue("hasAlpha", bm3.hasAlpha());
54
55        assertTrue("getConfig", bm1.getConfig() == Bitmap.Config.ARGB_8888);
56        assertTrue("getConfig", bm2.getConfig() == Bitmap.Config.RGB_565);
57        assertTrue("getConfig", bm3.getConfig() == Bitmap.Config.ARGB_4444);
58    }
59
60    @SmallTest
61    public void testMutability() throws Exception {
62        Bitmap bm1 = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888);
63        Bitmap bm2 = Bitmap.createBitmap(new int[100 * 200], 100, 200,
64                                         Bitmap.Config.ARGB_8888);
65
66        assertTrue("mutability", bm1.isMutable());
67        assertFalse("mutability", bm2.isMutable());
68
69        bm1.eraseColor(0);
70
71        try {
72            bm2.eraseColor(0);
73            fail("eraseColor should throw exception");
74        } catch (IllegalStateException ex) {
75            // safe to catch and ignore this
76        }
77    }
78
79    @SmallTest
80    public void testGetPixelsWithAlpha() throws Exception {
81        int[] colors = new int[100];
82        for (int i = 0; i < 100; i++) {
83            colors[i] = (0xFF << 24) | (i << 16) | (i << 8) | i;
84        }
85
86        Bitmap bm = Bitmap.createBitmap(colors, 10, 10,
87                                        Bitmap.Config.ARGB_8888);
88
89        int[] pixels = new int[100];
90        bm.getPixels(pixels, 0, 10, 0, 0, 10, 10);
91        for (int i = 0; i < 100; i++) {
92            int p = bm.getPixel(i % 10, i / 10);
93            assertEquals("getPixels", p, pixels[i]);
94        }
95
96        for (int i = 0; i < 100; i++) {
97            int p = bm.getPixel(i % 10, i / 10);
98            assertEquals("getPixel", p, colors[i]);
99            assertEquals("pixel value", p,
100                         ((0xFF << 24) | (i << 16) | (i << 8) | i));
101        }
102
103    }
104
105    @SmallTest
106    public void testGetPixelsWithoutAlpha() throws Exception {
107        int[] colors = new int[100];
108        for (int i = 0; i < 100; i++) {
109            colors[i] = (0xFF << 24) | (i << 16) | (i << 8) | i;
110        }
111
112        Bitmap bm = Bitmap.createBitmap(colors, 10, 10, Bitmap.Config.RGB_565);
113
114        int[] pixels = new int[100];
115        bm.getPixels(pixels, 0, 10, 0, 0, 10, 10);
116        for (int i = 0; i < 100; i++) {
117            int p = bm.getPixel(i % 10, i / 10);
118            assertEquals("getPixels", p, pixels[i]);
119        }
120    }
121
122    @SmallTest
123    public void testSetPixelsWithAlpha() throws Exception {
124        int[] colors = new int[100];
125        for (int i = 0; i < 100; i++) {
126            colors[i] = (0xFF << 24) | (i << 16) | (i << 8) | i;
127        }
128
129        Bitmap.Config config = Bitmap.Config.ARGB_8888;
130        Bitmap bm1 = Bitmap.createBitmap(colors, 10, 10, config);
131        Bitmap bm2 = Bitmap.createBitmap(10, 10, config);
132
133        for (int i = 0; i < 100; i++) {
134            bm2.setPixel(i % 10, i / 10, colors[i]);
135        }
136
137        for (int i = 0; i < 100; i++) {
138            assertEquals("setPixel",
139                    bm1.getPixel(i % 10, i / 10), bm2.getPixel(i % 10, i / 10));
140        }
141
142        for (int i = 0; i < 100; i++) {
143            assertEquals("setPixel value",
144                         bm1.getPixel(i % 10, i / 10), colors[i]);
145        }
146    }
147
148    @SmallTest
149    public void testSetPixelsWithoutAlpha() throws Exception {
150        int[] colors = new int[100];
151        for (int i = 0; i < 100; i++) {
152            colors[i] = (0xFF << 24) | (i << 16) | (i << 8) | i;
153        }
154
155        Bitmap.Config config = Bitmap.Config.RGB_565;
156        Bitmap bm1 = Bitmap.createBitmap(colors, 10, 10, config);
157        Bitmap bm2 = Bitmap.createBitmap(10, 10, config);
158
159        for (int i = 0; i < 100; i++) {
160            bm2.setPixel(i % 10, i / 10, colors[i]);
161        }
162
163        for (int i = 0; i < 100; i++) {
164            assertEquals("setPixel", bm1.getPixel(i % 10, i / 10),
165                         bm2.getPixel(i % 10, i / 10));
166        }
167    }
168
169    private static int computePrePostMul(int alpha, int comp) {
170        if (alpha == 0) {
171            return 0;
172        }
173        int premul = Math.round(alpha * comp / 255.f);
174        int unpre = Math.round(255.0f * premul / alpha);
175        return unpre;
176    }
177
178    @SmallTest
179    public void testSetPixelsWithNonOpaqueAlpha() throws Exception {
180        int[] colors = new int[256];
181        for (int i = 0; i < 256; i++) {
182            colors[i] = (i << 24) | (0xFF << 16) | (0x80 << 8) | 0;
183        }
184
185        Bitmap.Config config = Bitmap.Config.ARGB_8888;
186
187        // create a bitmap with the color array specified
188        Bitmap bm1 = Bitmap.createBitmap(colors, 16, 16, config);
189
190        // create a bitmap with no colors, but then call setPixels
191        Bitmap bm2 = Bitmap.createBitmap(16, 16, config);
192        bm2.setPixels(colors, 0, 16, 0, 0, 16, 16);
193
194        // now check that we did a good job returning the unpremultiplied alpha
195        final int tolerance = 1;
196        for (int i = 0; i < 256; i++) {
197            int c0 = colors[i];
198            int c1 = bm1.getPixel(i % 16, i / 16);
199            int c2 = bm2.getPixel(i % 16, i / 16);
200
201            // these two should always be identical
202            assertEquals("getPixel", c1, c2);
203
204            // comparing the original (c0) with the returned color is tricky,
205            // since it gets premultiplied during the set(), and unpremultiplied
206            // by the get().
207            int a0 = Color.alpha(c0);
208            int a1 = Color.alpha(c1);
209            assertEquals("alpha", a0, a1);
210
211            int r0 = Color.red(c0);
212            int r1 = Color.red(c1);
213            int rr = computePrePostMul(a0, r0);
214            assertTrue("red", Math.abs(rr - r1) <= tolerance);
215
216            int g0 = Color.green(c0);
217            int g1 = Color.green(c1);
218            int gg = computePrePostMul(a0, g0);
219            assertTrue("green", Math.abs(gg - g1) <= tolerance);
220
221            int b0 = Color.blue(c0);
222            int b1 = Color.blue(c1);
223            int bb = computePrePostMul(a0, b0);
224            assertTrue("blue", Math.abs(bb - b1) <= tolerance);
225
226            if (false) {
227                int cc = Color.argb(a0, rr, gg, bb);
228                android.util.Log.d("skia", "original " + Integer.toHexString(c0) +
229                                " set+get " + Integer.toHexString(c1) +
230                               " local " + Integer.toHexString(cc));
231            }
232        }
233    }
234}
235