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;
20
21import junit.framework.TestCase;
22
23
24public class BitmapTest extends TestCase {
25
26    @SmallTest
27    public void testBasic() throws Exception {
28        Bitmap bm1 = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888);
29        Bitmap bm2 = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
30        Bitmap bm3 = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_4444);
31
32        assertTrue("mutability", bm1.isMutable());
33        assertTrue("mutability", bm2.isMutable());
34        assertTrue("mutability", bm3.isMutable());
35
36        assertEquals("width", 100, bm1.getWidth());
37        assertEquals("width", 100, bm2.getWidth());
38        assertEquals("width", 100, bm3.getWidth());
39
40        assertEquals("rowbytes", 400, bm1.getRowBytes());
41        assertEquals("rowbytes", 200, bm2.getRowBytes());
42        assertEquals("rowbytes", 400, bm3.getRowBytes());
43
44        assertEquals("byteCount", 80000, bm1.getByteCount());
45        assertEquals("byteCount", 40000, bm2.getByteCount());
46        assertEquals("byteCount", 80000, bm3.getByteCount());
47
48        assertEquals("height", 200, bm1.getHeight());
49        assertEquals("height", 200, bm2.getHeight());
50        assertEquals("height", 200, bm3.getHeight());
51
52        assertTrue("hasAlpha", bm1.hasAlpha());
53        assertFalse("hasAlpha", bm2.hasAlpha());
54        assertTrue("hasAlpha", bm3.hasAlpha());
55
56        assertTrue("getConfig", bm1.getConfig() == Bitmap.Config.ARGB_8888);
57        assertTrue("getConfig", bm2.getConfig() == Bitmap.Config.RGB_565);
58        assertTrue("getConfig", bm3.getConfig() == Bitmap.Config.ARGB_8888);
59    }
60
61    @SmallTest
62    public void testMutability() throws Exception {
63        Bitmap bm1 = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888);
64        Bitmap bm2 = Bitmap.createBitmap(new int[100 * 200], 100, 200,
65                                         Bitmap.Config.ARGB_8888);
66
67        assertTrue("mutability", bm1.isMutable());
68        assertFalse("mutability", bm2.isMutable());
69
70        bm1.eraseColor(0);
71
72        try {
73            bm2.eraseColor(0);
74            fail("eraseColor should throw exception");
75        } catch (IllegalStateException ex) {
76            // safe to catch and ignore this
77        }
78    }
79
80    @SmallTest
81    public void testGetPixelsWithAlpha() throws Exception {
82        int[] colors = new int[100];
83        for (int i = 0; i < 100; i++) {
84            colors[i] = (0xFF << 24) | (i << 16) | (i << 8) | i;
85        }
86
87        Bitmap bm = Bitmap.createBitmap(colors, 10, 10,
88                                        Bitmap.Config.ARGB_8888);
89
90        int[] pixels = new int[100];
91        bm.getPixels(pixels, 0, 10, 0, 0, 10, 10);
92        for (int i = 0; i < 100; i++) {
93            int p = bm.getPixel(i % 10, i / 10);
94            assertEquals("getPixels", p, pixels[i]);
95        }
96
97        for (int i = 0; i < 100; i++) {
98            int p = bm.getPixel(i % 10, i / 10);
99            assertEquals("getPixel", p, colors[i]);
100            assertEquals("pixel value", p,
101                         ((0xFF << 24) | (i << 16) | (i << 8) | i));
102        }
103
104    }
105
106    @SmallTest
107    public void testGetPixelsWithoutAlpha() throws Exception {
108        int[] colors = new int[100];
109        for (int i = 0; i < 100; i++) {
110            colors[i] = (0xFF << 24) | (i << 16) | (i << 8) | i;
111        }
112
113        Bitmap bm = Bitmap.createBitmap(colors, 10, 10, Bitmap.Config.RGB_565);
114
115        int[] pixels = new int[100];
116        bm.getPixels(pixels, 0, 10, 0, 0, 10, 10);
117        for (int i = 0; i < 100; i++) {
118            int p = bm.getPixel(i % 10, i / 10);
119            assertEquals("getPixels", p, pixels[i]);
120        }
121    }
122
123    @SmallTest
124    public void testSetPixelsWithAlpha() throws Exception {
125        int[] colors = new int[100];
126        for (int i = 0; i < 100; i++) {
127            colors[i] = (0xFF << 24) | (i << 16) | (i << 8) | i;
128        }
129
130        Bitmap.Config config = Bitmap.Config.ARGB_8888;
131        Bitmap bm1 = Bitmap.createBitmap(colors, 10, 10, config);
132        Bitmap bm2 = Bitmap.createBitmap(10, 10, config);
133
134        for (int i = 0; i < 100; i++) {
135            bm2.setPixel(i % 10, i / 10, colors[i]);
136        }
137
138        for (int i = 0; i < 100; i++) {
139            assertEquals("setPixel",
140                    bm1.getPixel(i % 10, i / 10), bm2.getPixel(i % 10, i / 10));
141        }
142
143        for (int i = 0; i < 100; i++) {
144            assertEquals("setPixel value",
145                         bm1.getPixel(i % 10, i / 10), colors[i]);
146        }
147    }
148
149    @SmallTest
150    public void testSetPixelsWithoutAlpha() throws Exception {
151        int[] colors = new int[100];
152        for (int i = 0; i < 100; i++) {
153            colors[i] = (0xFF << 24) | (i << 16) | (i << 8) | i;
154        }
155
156        Bitmap.Config config = Bitmap.Config.RGB_565;
157        Bitmap bm1 = Bitmap.createBitmap(colors, 10, 10, config);
158        Bitmap bm2 = Bitmap.createBitmap(10, 10, config);
159
160        for (int i = 0; i < 100; i++) {
161            bm2.setPixel(i % 10, i / 10, colors[i]);
162        }
163
164        for (int i = 0; i < 100; i++) {
165            assertEquals("setPixel", bm1.getPixel(i % 10, i / 10),
166                         bm2.getPixel(i % 10, i / 10));
167        }
168    }
169
170    private static int computePrePostMul(int alpha, int comp) {
171        if (alpha == 0) {
172            return 0;
173        }
174        int premul = Math.round(alpha * comp / 255.f);
175        int unpre = Math.round(255.0f * premul / alpha);
176        return unpre;
177    }
178
179    @SmallTest
180    public void testSetPixelsWithNonOpaqueAlpha() throws Exception {
181        int[] colors = new int[256];
182        for (int i = 0; i < 256; i++) {
183            colors[i] = (i << 24) | (0xFF << 16) | (0x80 << 8) | 0;
184        }
185
186        Bitmap.Config config = Bitmap.Config.ARGB_8888;
187
188        // create a bitmap with the color array specified
189        Bitmap bm1 = Bitmap.createBitmap(colors, 16, 16, config);
190
191        // create a bitmap with no colors, but then call setPixels
192        Bitmap bm2 = Bitmap.createBitmap(16, 16, config);
193        bm2.setPixels(colors, 0, 16, 0, 0, 16, 16);
194
195        // now check that we did a good job returning the unpremultiplied alpha
196        final int tolerance = 1;
197        for (int i = 0; i < 256; i++) {
198            int c0 = colors[i];
199            int c1 = bm1.getPixel(i % 16, i / 16);
200            int c2 = bm2.getPixel(i % 16, i / 16);
201
202            // these two should always be identical
203            assertEquals("getPixel", c1, c2);
204
205            // comparing the original (c0) with the returned color is tricky,
206            // since it gets premultiplied during the set(), and unpremultiplied
207            // by the get().
208            int a0 = Color.alpha(c0);
209            int a1 = Color.alpha(c1);
210            assertEquals("alpha", a0, a1);
211
212            int r0 = Color.red(c0);
213            int r1 = Color.red(c1);
214            int rr = computePrePostMul(a0, r0);
215            assertTrue("red", Math.abs(rr - r1) <= tolerance);
216
217            int g0 = Color.green(c0);
218            int g1 = Color.green(c1);
219            int gg = computePrePostMul(a0, g0);
220            assertTrue("green", Math.abs(gg - g1) <= tolerance);
221
222            int b0 = Color.blue(c0);
223            int b1 = Color.blue(c1);
224            int bb = computePrePostMul(a0, b0);
225            assertTrue("blue", Math.abs(bb - b1) <= tolerance);
226
227            if (false) {
228                int cc = Color.argb(a0, rr, gg, bb);
229                android.util.Log.d("skia", "original " + Integer.toHexString(c0) +
230                                " set+get " + Integer.toHexString(c1) +
231                               " local " + Integer.toHexString(cc));
232            }
233        }
234    }
235
236    @SmallTest
237    public void testCreateHardwareBitmapFromGraphicBuffer() {
238        GraphicBuffer buffer = GraphicBuffer.create(10, 10, PixelFormat.RGBA_8888,
239                GraphicBuffer.USAGE_HW_TEXTURE | GraphicBuffer.USAGE_SOFTWARE_MASK);
240        Canvas canvas = buffer.lockCanvas();
241        canvas.drawColor(Color.YELLOW);
242        buffer.unlockCanvasAndPost(canvas);
243        Bitmap hardwareBitmap = Bitmap.createHardwareBitmap(buffer);
244        assertTrue(hardwareBitmap.isPremultiplied());
245        assertFalse(hardwareBitmap.isMutable());
246    }
247}
248