Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 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 | |
| 17 | package android.graphics.drawable; |
| 18 | |
Robin Lee | 76dc52a | 2018-01-04 17:50:18 +0100 | [diff] [blame] | 19 | import static com.google.common.truth.Truth.assertThat; |
| 20 | |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 21 | import android.graphics.Bitmap; |
| 22 | import android.graphics.Canvas; |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 23 | import android.graphics.Region; |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 24 | import android.os.Handler; |
| 25 | import android.os.HandlerThread; |
| 26 | import android.os.Parcel; |
| 27 | import android.test.AndroidTestCase; |
| 28 | import android.test.suitebuilder.annotation.SmallTest; |
| 29 | import android.util.Log; |
| 30 | |
sergeyv | aad8ae3 | 2017-02-28 18:28:27 -0800 | [diff] [blame] | 31 | import com.android.frameworks.coretests.R; |
| 32 | |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 33 | import java.io.ByteArrayOutputStream; |
| 34 | import java.io.File; |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 35 | import java.io.FileOutputStream; |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 36 | import java.util.ArrayList; |
sergeyv | aad8ae3 | 2017-02-28 18:28:27 -0800 | [diff] [blame] | 37 | import java.util.Arrays; |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 38 | |
| 39 | public class IconTest extends AndroidTestCase { |
| 40 | public static final String TAG = IconTest.class.getSimpleName(); |
| 41 | public static void L(String s, Object... parts) { |
| 42 | Log.d(TAG, (parts.length == 0) ? s : String.format(s, parts)); |
| 43 | } |
| 44 | |
| 45 | @SmallTest |
| 46 | public void testWithBitmap() throws Exception { |
| 47 | final Bitmap bm1 = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888); |
| 48 | final Bitmap bm2 = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565); |
| 49 | final Bitmap bm3 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape)) |
| 50 | .getBitmap(); |
| 51 | |
| 52 | final Canvas can1 = new Canvas(bm1); |
| 53 | can1.drawColor(0xFFFF0000); |
| 54 | final Canvas can2 = new Canvas(bm2); |
| 55 | can2.drawColor(0xFF00FF00); |
| 56 | |
| 57 | final Icon im1 = Icon.createWithBitmap(bm1); |
| 58 | final Icon im2 = Icon.createWithBitmap(bm2); |
| 59 | final Icon im3 = Icon.createWithBitmap(bm3); |
| 60 | |
| 61 | final Drawable draw1 = im1.loadDrawable(mContext); |
| 62 | final Drawable draw2 = im2.loadDrawable(mContext); |
| 63 | final Drawable draw3 = im3.loadDrawable(mContext); |
| 64 | |
| 65 | final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(), |
| 66 | draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); |
| 67 | final Bitmap test2 = Bitmap.createBitmap(draw2.getIntrinsicWidth(), |
| 68 | draw2.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); |
| 69 | final Bitmap test3 = Bitmap.createBitmap(draw3.getIntrinsicWidth(), |
| 70 | draw3.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); |
| 71 | |
| 72 | draw1.setBounds(0, 0, draw1.getIntrinsicWidth(), draw1.getIntrinsicHeight()); |
| 73 | draw1.draw(new Canvas(test1)); |
| 74 | |
| 75 | draw2.setBounds(0, 0, draw2.getIntrinsicWidth(), draw2.getIntrinsicHeight()); |
| 76 | draw2.draw(new Canvas(test2)); |
| 77 | |
| 78 | draw3.setBounds(0, 0, draw3.getIntrinsicWidth(), draw3.getIntrinsicHeight()); |
| 79 | draw3.draw(new Canvas(test3)); |
| 80 | |
| 81 | final File dir = getContext().getExternalFilesDir(null); |
| 82 | L("writing temp bitmaps to %s...", dir); |
| 83 | |
| 84 | bm1.compress(Bitmap.CompressFormat.PNG, 100, |
| 85 | new FileOutputStream(new File(dir, "bitmap1-original.png"))); |
| 86 | test1.compress(Bitmap.CompressFormat.PNG, 100, |
| 87 | new FileOutputStream(new File(dir, "bitmap1-test.png"))); |
| 88 | if (!equalBitmaps(bm1, test1)) { |
| 89 | findBitmapDifferences(bm1, test1); |
| 90 | fail("bitmap1 differs, check " + dir); |
| 91 | } |
| 92 | |
| 93 | bm2.compress(Bitmap.CompressFormat.PNG, 100, |
| 94 | new FileOutputStream(new File(dir, "bitmap2-original.png"))); |
| 95 | test2.compress(Bitmap.CompressFormat.PNG, 100, |
| 96 | new FileOutputStream(new File(dir, "bitmap2-test.png"))); |
| 97 | if (!equalBitmaps(bm2, test2)) { |
| 98 | findBitmapDifferences(bm2, test2); |
| 99 | fail("bitmap2 differs, check " + dir); |
| 100 | } |
| 101 | |
| 102 | bm3.compress(Bitmap.CompressFormat.PNG, 100, |
| 103 | new FileOutputStream(new File(dir, "bitmap3-original.png"))); |
| 104 | test3.compress(Bitmap.CompressFormat.PNG, 100, |
| 105 | new FileOutputStream(new File(dir, "bitmap3-test.png"))); |
| 106 | if (!equalBitmaps(bm3, test3)) { |
| 107 | findBitmapDifferences(bm3, test3); |
| 108 | fail("bitmap3 differs, check " + dir); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | @SmallTest |
Robin Lee | 76dc52a | 2018-01-04 17:50:18 +0100 | [diff] [blame] | 113 | public void testScaleDownIfNecessary() throws Exception { |
| 114 | final Bitmap bm = Bitmap.createBitmap(4321, 78, Bitmap.Config.ARGB_8888); |
| 115 | final Icon ic = Icon.createWithBitmap(bm); |
| 116 | ic.scaleDownIfNecessary(40, 20); |
| 117 | |
| 118 | assertThat(bm.getWidth()).isEqualTo(4321); |
| 119 | assertThat(bm.getHeight()).isEqualTo(78); |
| 120 | |
| 121 | assertThat(ic.getBitmap().getWidth()).isLessThan(41); |
| 122 | assertThat(ic.getBitmap().getHeight()).isLessThan(21); |
| 123 | } |
| 124 | |
| 125 | @SmallTest |
Hyunyoung Song | e4179e2 | 2017-03-01 12:51:26 -0800 | [diff] [blame] | 126 | public void testWithAdaptiveBitmap() throws Exception { |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 127 | final Bitmap bm1 = Bitmap.createBitmap(150, 150, Bitmap.Config.ARGB_8888); |
| 128 | |
| 129 | final Canvas can1 = new Canvas(bm1); |
| 130 | can1.drawColor(0xFFFF0000); |
| 131 | |
Hyunyoung Song | e4179e2 | 2017-03-01 12:51:26 -0800 | [diff] [blame] | 132 | final Icon im1 = Icon.createWithAdaptiveBitmap(bm1); |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 133 | |
Hyunyoung Song | be8835e | 2017-02-17 11:25:08 -0800 | [diff] [blame] | 134 | final AdaptiveIconDrawable draw1 = (AdaptiveIconDrawable) im1.loadDrawable(mContext); |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 135 | |
| 136 | final Bitmap test1 = Bitmap.createBitmap( |
Hyunyoung Song | 92e3da2 | 2017-04-06 23:04:19 -0700 | [diff] [blame] | 137 | (int)(draw1.getIntrinsicWidth() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction())), |
| 138 | (int)(draw1.getIntrinsicHeight() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction())), |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 139 | Bitmap.Config.ARGB_8888); |
| 140 | |
| 141 | draw1.setBounds(0, 0, |
Hyunyoung Song | 92e3da2 | 2017-04-06 23:04:19 -0700 | [diff] [blame] | 142 | (int) (draw1.getIntrinsicWidth() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction())), |
| 143 | (int) (draw1.getIntrinsicHeight() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction()))); |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 144 | draw1.draw(new Canvas(test1)); |
| 145 | |
| 146 | final File dir = getContext().getExternalFilesDir(null); |
| 147 | L("writing temp bitmaps to %s...", dir); |
| 148 | |
| 149 | bm1.compress(Bitmap.CompressFormat.PNG, 100, |
Hyunyoung Song | e4179e2 | 2017-03-01 12:51:26 -0800 | [diff] [blame] | 150 | new FileOutputStream(new File(dir, "adaptive-bitmap1-original.png"))); |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 151 | test1.compress(Bitmap.CompressFormat.PNG, 100, |
Hyunyoung Song | e4179e2 | 2017-03-01 12:51:26 -0800 | [diff] [blame] | 152 | new FileOutputStream(new File(dir, "adaptive-bitmap1-test.png"))); |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 153 | if (!equalBitmaps(bm1, test1, draw1.getSafeZone())) { |
| 154 | findBitmapDifferences(bm1, test1); |
Hyunyoung Song | e4179e2 | 2017-03-01 12:51:26 -0800 | [diff] [blame] | 155 | fail("adaptive bitmap1 differs, check " + dir); |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 156 | } |
| 157 | } |
| 158 | |
| 159 | @SmallTest |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 160 | public void testWithBitmapResource() throws Exception { |
| 161 | final Bitmap res1 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape)) |
| 162 | .getBitmap(); |
| 163 | |
Dan Sandler | 02cd9f9 | 2015-05-14 11:44:32 -0400 | [diff] [blame] | 164 | final Icon im1 = Icon.createWithResource(getContext(), R.drawable.landscape); |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 165 | final Drawable draw1 = im1.loadDrawable(mContext); |
| 166 | final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(), |
| 167 | draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); |
| 168 | draw1.setBounds(0, 0, test1.getWidth(), test1.getHeight()); |
| 169 | draw1.draw(new Canvas(test1)); |
| 170 | |
| 171 | final File dir = getContext().getExternalFilesDir(null); |
| 172 | res1.compress(Bitmap.CompressFormat.PNG, 100, |
| 173 | new FileOutputStream(new File(dir, "res1-original.png"))); |
| 174 | test1.compress(Bitmap.CompressFormat.PNG, 100, |
| 175 | new FileOutputStream(new File(dir, "res1-test.png"))); |
| 176 | if (!equalBitmaps(res1, test1)) { |
| 177 | findBitmapDifferences(res1, test1); |
| 178 | fail("res1 differs, check " + dir); |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | @SmallTest |
| 183 | public void testWithFile() throws Exception { |
| 184 | final Bitmap bit1 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape)) |
| 185 | .getBitmap(); |
| 186 | final File dir = getContext().getExternalFilesDir(null); |
| 187 | final File file1 = new File(dir, "file1-original.png"); |
| 188 | bit1.compress(Bitmap.CompressFormat.PNG, 100, |
| 189 | new FileOutputStream(file1)); |
| 190 | |
| 191 | final Icon im1 = Icon.createWithFilePath(file1.toString()); |
| 192 | final Drawable draw1 = im1.loadDrawable(mContext); |
| 193 | final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(), |
| 194 | draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); |
| 195 | draw1.setBounds(0, 0, test1.getWidth(), test1.getHeight()); |
| 196 | draw1.draw(new Canvas(test1)); |
| 197 | |
| 198 | test1.compress(Bitmap.CompressFormat.PNG, 100, |
| 199 | new FileOutputStream(new File(dir, "file1-test.png"))); |
| 200 | if (!equalBitmaps(bit1, test1)) { |
| 201 | findBitmapDifferences(bit1, test1); |
| 202 | fail("testWithFile: file1 differs, check " + dir); |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | @SmallTest |
| 207 | public void testAsync() throws Exception { |
| 208 | final Bitmap bit1 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape)) |
| 209 | .getBitmap(); |
| 210 | final File dir = getContext().getExternalFilesDir(null); |
| 211 | final File file1 = new File(dir, "async-original.png"); |
| 212 | bit1.compress(Bitmap.CompressFormat.PNG, 100, |
| 213 | new FileOutputStream(file1)); |
| 214 | |
| 215 | final Icon im1 = Icon.createWithFilePath(file1.toString()); |
| 216 | final HandlerThread thd = new HandlerThread("testAsync"); |
| 217 | thd.start(); |
| 218 | final Handler h = new Handler(thd.getLooper()); |
| 219 | L(TAG, "asyncTest: dispatching load to thread: " + thd); |
Dan Sandler | 877d696 | 2015-05-13 10:51:52 -0400 | [diff] [blame] | 220 | im1.loadDrawableAsync(mContext, new Icon.OnDrawableLoadedListener() { |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 221 | @Override |
| 222 | public void onDrawableLoaded(Drawable draw1) { |
| 223 | L(TAG, "asyncTest: thread: loading drawable"); |
| 224 | L(TAG, "asyncTest: thread: loaded: %dx%d", draw1.getIntrinsicWidth(), |
| 225 | draw1.getIntrinsicHeight()); |
| 226 | final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(), |
| 227 | draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); |
| 228 | draw1.setBounds(0, 0, test1.getWidth(), test1.getHeight()); |
| 229 | draw1.draw(new Canvas(test1)); |
| 230 | |
| 231 | try { |
| 232 | test1.compress(Bitmap.CompressFormat.PNG, 100, |
| 233 | new FileOutputStream(new File(dir, "async-test.png"))); |
| 234 | } catch (java.io.FileNotFoundException ex) { |
| 235 | fail("couldn't create test file: " + ex); |
| 236 | } |
| 237 | if (!equalBitmaps(bit1, test1)) { |
| 238 | findBitmapDifferences(bit1, test1); |
| 239 | fail("testAsync: file1 differs, check " + dir); |
| 240 | } |
| 241 | } |
Dan Sandler | 877d696 | 2015-05-13 10:51:52 -0400 | [diff] [blame] | 242 | }, h); |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 243 | L(TAG, "asyncTest: awaiting result"); |
| 244 | Thread.sleep(500); // ;_; |
| 245 | assertTrue("async-test.png does not exist!", new File(dir, "async-test.png").exists()); |
| 246 | L(TAG, "asyncTest: done"); |
| 247 | } |
| 248 | |
| 249 | @SmallTest |
| 250 | public void testParcel() throws Exception { |
| 251 | final Bitmap originalbits = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape)) |
| 252 | .getBitmap(); |
| 253 | |
| 254 | final ByteArrayOutputStream ostream = new ByteArrayOutputStream( |
| 255 | originalbits.getWidth() * originalbits.getHeight() * 2); // guess 50% compression |
| 256 | originalbits.compress(Bitmap.CompressFormat.PNG, 100, ostream); |
| 257 | final byte[] pngdata = ostream.toByteArray(); |
| 258 | |
| 259 | L("starting testParcel; bitmap: %d bytes, PNG: %d bytes", |
| 260 | originalbits.getByteCount(), |
| 261 | pngdata.length); |
| 262 | |
| 263 | final File dir = getContext().getExternalFilesDir(null); |
| 264 | final File originalfile = new File(dir, "parcel-original.png"); |
| 265 | new FileOutputStream(originalfile).write(pngdata); |
| 266 | |
| 267 | ArrayList<Icon> imgs = new ArrayList<>(); |
| 268 | final Icon file1 = Icon.createWithFilePath(originalfile.getAbsolutePath()); |
| 269 | imgs.add(file1); |
| 270 | final Icon bit1 = Icon.createWithBitmap(originalbits); |
| 271 | imgs.add(bit1); |
| 272 | final Icon data1 = Icon.createWithData(pngdata, 0, pngdata.length); |
| 273 | imgs.add(data1); |
Dan Sandler | 02cd9f9 | 2015-05-14 11:44:32 -0400 | [diff] [blame] | 274 | final Icon res1 = Icon.createWithResource(getContext(), R.drawable.landscape); |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 275 | imgs.add(res1); |
| 276 | |
| 277 | ArrayList<Icon> test = new ArrayList<>(); |
| 278 | final Parcel parcel = Parcel.obtain(); |
| 279 | int pos = 0; |
| 280 | parcel.writeInt(imgs.size()); |
| 281 | for (Icon img : imgs) { |
| 282 | img.writeToParcel(parcel, 0); |
| 283 | L("used %d bytes parceling: %s", parcel.dataPosition() - pos, img); |
| 284 | pos = parcel.dataPosition(); |
| 285 | } |
| 286 | |
| 287 | parcel.setDataPosition(0); // rewind |
| 288 | final int N = parcel.readInt(); |
| 289 | for (int i=0; i<N; i++) { |
| 290 | Icon img = Icon.CREATOR.createFromParcel(parcel); |
| 291 | L("test %d: read from parcel: %s", i, img); |
| 292 | final File testfile = new File(dir, |
| 293 | String.format("parcel-test%02d.png", i)); |
| 294 | |
| 295 | final Drawable draw1 = img.loadDrawable(mContext); |
| 296 | if (draw1 == null) { |
| 297 | fail("null drawable from img: " + img); |
| 298 | } |
| 299 | final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(), |
| 300 | draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); |
| 301 | draw1.setBounds(0, 0, test1.getWidth(), test1.getHeight()); |
| 302 | draw1.draw(new Canvas(test1)); |
| 303 | |
| 304 | try { |
| 305 | test1.compress(Bitmap.CompressFormat.PNG, 100, |
| 306 | new FileOutputStream(testfile)); |
| 307 | } catch (java.io.FileNotFoundException ex) { |
| 308 | fail("couldn't create test file " + testfile + ": " + ex); |
| 309 | } |
| 310 | if (!equalBitmaps(originalbits, test1)) { |
| 311 | findBitmapDifferences(originalbits, test1); |
| 312 | fail(testfile + " differs from original: " + originalfile); |
| 313 | } |
| 314 | |
| 315 | } |
| 316 | } |
| 317 | |
| 318 | |
| 319 | // ======== utils ======== |
| 320 | |
| 321 | static final char[] GRADIENT = " .:;+=xX$#".toCharArray(); |
| 322 | static float[] hsv = new float[3]; |
| 323 | static char colorToChar(int color) { |
| 324 | int sum = ((color >> 16) & 0xff) |
| 325 | + ((color >> 8) & 0xff) |
| 326 | + ((color) & 0xff); |
| 327 | return GRADIENT[sum * (GRADIENT.length-1) / (3*0xff)]; |
| 328 | } |
| 329 | static void printBits(int[] a, int w, int h) { |
| 330 | final StringBuilder sb = new StringBuilder(); |
| 331 | for (int i=0; i<w; i++) { |
| 332 | for (int j=0; j<h; j++) { |
| 333 | sb.append(colorToChar(a[i+w*j])); |
| 334 | } |
| 335 | sb.append('\n'); |
| 336 | } |
| 337 | L(sb.toString()); |
| 338 | } |
| 339 | static void printBits(Bitmap a) { |
| 340 | final int w = a.getWidth(); |
| 341 | final int h = a.getHeight(); |
| 342 | int[] aPix = new int[w * h]; |
| 343 | printBits(aPix, w, h); |
| 344 | } |
| 345 | boolean equalBitmaps(Bitmap a, Bitmap b) { |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 346 | return equalBitmaps(a, b, null); |
| 347 | } |
| 348 | |
| 349 | boolean equalBitmaps(Bitmap a, Bitmap b, Region region) { |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 350 | if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) return false; |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 351 | |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 352 | final int w = a.getWidth(); |
| 353 | final int h = a.getHeight(); |
| 354 | int[] aPix = new int[w * h]; |
| 355 | int[] bPix = new int[w * h]; |
| 356 | |
Hyunyoung Song | 9ee90a4 | 2017-02-03 15:53:26 -0800 | [diff] [blame] | 357 | if (region != null) { |
| 358 | for (int i = 0; i < w; i++) { |
| 359 | for (int j = 0; j < h; j++) { |
| 360 | if (region.contains(i, j) && a.getPixel(i, j) != b.getPixel(i, j)) { |
| 361 | return false; |
| 362 | } |
| 363 | } |
| 364 | } |
| 365 | return true; |
| 366 | } else { |
| 367 | a.getPixels(aPix, 0, w, 0, 0, w, h); |
| 368 | b.getPixels(bPix, 0, w, 0, 0, w, h); |
| 369 | return Arrays.equals(aPix, bPix); |
| 370 | } |
Dan Sandler | b9f7aac3 | 2015-03-04 13:08:49 -0500 | [diff] [blame] | 371 | } |
| 372 | |
| 373 | void findBitmapDifferences(Bitmap a, Bitmap b) { |
| 374 | if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) { |
| 375 | L("different sizes: %dx%d vs %dx%d", |
| 376 | a.getWidth(), a.getHeight(), b.getWidth(), b.getHeight()); |
| 377 | return; |
| 378 | } |
| 379 | |
| 380 | final int w = a.getWidth(); |
| 381 | final int h = a.getHeight(); |
| 382 | int[] aPix = new int[w * h]; |
| 383 | int[] bPix = new int[w * h]; |
| 384 | |
| 385 | a.getPixels(aPix, 0, w, 0, 0, w, h); |
| 386 | b.getPixels(bPix, 0, w, 0, 0, w, h); |
| 387 | |
| 388 | L("bitmap a (%dx%d)", w, h); |
| 389 | printBits(aPix, w, h); |
| 390 | L("bitmap b (%dx%d)", w, h); |
| 391 | printBits(bPix, w, h); |
| 392 | |
| 393 | StringBuffer sb = new StringBuffer("Different pixels: "); |
| 394 | for (int i=0; i<w; i++) { |
| 395 | for (int j=0; j<h; j++) { |
| 396 | if (aPix[i+w*j] != bPix[i+w*j]) { |
| 397 | sb.append(" ").append(i).append(",").append(j); |
| 398 | } |
| 399 | } |
| 400 | } |
| 401 | L(sb.toString()); |
| 402 | } |
| 403 | } |