Extended BitmapRegionDecoderTest for WEBP image.

Added WebP image to the list of images tested for BitmapRegionDecoder
functionality.
- In the last patch, some of the testcases got left w.r.t WEBP.
- WEBP Region Decoder for RGB_565 color mode requires more MSE Margin.
  Refactored the tests to specify the MSE Margin for individual cases.
- Added separate distance function for RGB_565 color-space.
- Rolled back the last patch. Investigated it further and found that
  irrespective of the color-space, the Bitmap.getPixels() returns the
  'int' (4 bytes) for a pixel corresponding to ARGB channels (8 bits each).
  Not sure, where but (5,6,5) bits of RGB_565 pixel are converted to 8 bits each
  by logic (r[4..0] << 3 | r[4..0] >> 5, g[5..0] << 2 | g[5..0] >> 6,
  b[4..0] << 3 | b[4..0] >> 5).
  Similarly for ARGB_4444 pixel, the 4 bits per channel are converted to
  8 bits (r[3..0] << 4 | r[3..0] and so on).
- Added decoder test for other color-configs for BitmapFactory class as
  well.

Change-Id: Ib885cdae6f24052aa17269950eed7b527ef1921b
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
index d7d5ff6..73a712b 100755
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
@@ -71,6 +71,11 @@
     private static int WIDTHS[] = new int[] { 1280, 640, 320, 320, 640 };
     private static int HEIGHTS[] = new int[] { 960, 480, 240, 240, 480 };
 
+    // Configurations for BitmapFactory.Options
+    private static Config[] COLOR_CONFIGS = new Config[] {Config.ARGB_8888, Config.RGB_565,
+        Config.ARGB_4444};
+    private static int[] COLOR_TOLS = new int[] {16, 49, 576};
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -228,29 +233,30 @@
     )
     public void testDecodeStream4() throws IOException {
         BitmapFactory.Options options = new BitmapFactory.Options();
-        options.inPreferredConfig = Config.ARGB_8888;
-        final int kErrorTol = 16;
+        for (int k = 0; k < COLOR_CONFIGS.length; ++k) {
+            options.inPreferredConfig = COLOR_CONFIGS[k];
 
-        // Decode the PNG & WebP test images. The WebP test image has been encoded from PNG test
-        // image and should have same similar (within some error-tolerance) Bitmap data.
-        InputStream iStreamPng = obtainInputStream(R.drawable.png_test);
-        Bitmap bPng = BitmapFactory.decodeStream(iStreamPng, null, options);
-        assertNotNull(bPng);
-        assertEquals(bPng.getConfig(), Config.ARGB_8888);
+            // Decode the PNG & WebP test images. The WebP test image has been encoded from PNG test
+            // image and should have same similar (within some error-tolerance) Bitmap data.
+            InputStream iStreamPng = obtainInputStream(R.drawable.png_test);
+            Bitmap bPng = BitmapFactory.decodeStream(iStreamPng, null, options);
+            assertNotNull(bPng);
+            assertEquals(bPng.getConfig(), COLOR_CONFIGS[k]);
 
-        InputStream iStreamWebp1 = obtainInputStream(R.drawable.webp_test);
-        Bitmap bWebp1 = BitmapFactory.decodeStream(iStreamWebp1, null, options);
-        assertNotNull(bWebp1);
-        compareBitmaps(bPng, bWebp1, kErrorTol, true);
+            InputStream iStreamWebp1 = obtainInputStream(R.drawable.webp_test);
+            Bitmap bWebp1 = BitmapFactory.decodeStream(iStreamWebp1, null, options);
+            assertNotNull(bWebp1);
+            compareBitmaps(bPng, bWebp1, COLOR_TOLS[k], true);
 
-        // Compress the PNG image to WebP format (Quality=90) and decode it back.
-        // This will test end-to-end WebP encoding and decoding.
-        ByteArrayOutputStream oStreamWebp = new ByteArrayOutputStream();
-        assertTrue(bPng.compress(CompressFormat.WEBP, 90, oStreamWebp));
-        InputStream iStreamWebp2 = new ByteArrayInputStream(oStreamWebp.toByteArray());
-        Bitmap bWebp2 = BitmapFactory.decodeStream(iStreamWebp2, null, options);
-        assertNotNull(bWebp2);
-        compareBitmaps(bPng, bWebp2, kErrorTol, true);
+            // Compress the PNG image to WebP format (Quality=90) and decode it back.
+            // This will test end-to-end WebP encoding and decoding.
+            ByteArrayOutputStream oStreamWebp = new ByteArrayOutputStream();
+            assertTrue(bPng.compress(CompressFormat.WEBP, 90, oStreamWebp));
+            InputStream iStreamWebp2 = new ByteArrayInputStream(oStreamWebp.toByteArray());
+            Bitmap bWebp2 = BitmapFactory.decodeStream(iStreamWebp2, null, options);
+            assertNotNull(bWebp2);
+            compareBitmaps(bPng, bWebp2, COLOR_TOLS[k], true);
+        }
     }
 
     @TestTargetNew(
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
index abbba4b..93d8bd6 100755
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
@@ -53,27 +53,28 @@
     private Resources mRes;
 
     // The test images, including baseline JPEGs and progressive JPEGs, a PNG,
-    // a GIF and a BMP.
+    // a WEBP, a GIF and a BMP.
     private static int[] RES_IDS = new int[] {
             R.drawable.baseline_jpeg, R.drawable.progressive_jpeg,
             R.drawable.baseline_restart_jpeg,
             R.drawable.progressive_restart_jpeg,
-            R.drawable.png_test, R.drawable.gif_test, R.drawable.bmp_test
+            R.drawable.png_test, R.drawable.webp_test,
+            R.drawable.gif_test, R.drawable.bmp_test
     };
     private static String[] NAMES_TEMP_FILES = new String[] {
-        "baseline_temp.jpg", "progressive_temp.jpg", "baseline_restart_temp.jpg"
-        , "progressive_restart_temp.jpg", "png_temp.png", "gif_temp.gif",
-        "bmp_temp.bmp"
+        "baseline_temp.jpg", "progressive_temp.jpg", "baseline_restart_temp.jpg",
+        "progressive_restart_temp.jpg", "png_temp.png", "webp_temp.webp",
+        "gif_temp.gif", "bmp_temp.bmp"
     };
 
     // The width and height of the above image.
     // -1 denotes that the image format is not supported by BitmapRegionDecoder
     private static int WIDTHS[] = new int[] {
-            1280, 1280, 1280, 1280, 640, -1, -1};
-    private static int HEIGHTS[] = new int[] {960, 960, 960, 960, 480, -1, -1};
+            1280, 1280, 1280, 1280, 640, 640, -1, -1};
+    private static int HEIGHTS[] = new int[] {960, 960, 960, 960, 480, 480, -1, -1};
 
     // The number of test images, format of which is supported by BitmapRegionDecoder
-    private static int NUM_TEST_IMAGES = 5;
+    private static int NUM_TEST_IMAGES = 6;
 
     private static int TILE_SIZE = 256;
 
@@ -91,6 +92,9 @@
     // square error of 3 * (1 * 1) among the RGB values.
     private int mMseMargin = 3 * (1 * 1);
 
+    // MSE margin for WebP Region-Decoding for 'Config.RGB_565' is little bigger.
+    private int mMseMarginWebPConfigRgb565 = 5;
+
 
     @Override
     protected void setUp() throws Exception {
@@ -195,7 +199,12 @@
                     InputStream is2 = obtainInputStream(RES_IDS[i]);
                     Bitmap wholeImage = BitmapFactory.decodeStream(is2, null, opts);
 
-                    compareRegionByRegion(decoder, opts, wholeImage);
+                    if (RES_IDS[i] == R.drawable.webp_test && COLOR_CONFIGS[k] == Config.RGB_565) {
+                        compareRegionByRegion(decoder, opts, mMseMarginWebPConfigRgb565,
+                                              wholeImage);
+                    } else {
+                        compareRegionByRegion(decoder, opts, mMseMargin, wholeImage);
+                    }
                     wholeImage.recycle();
                 }
             }
@@ -221,7 +230,12 @@
                     Bitmap wholeImage = BitmapFactory.decodeByteArray(imageData,
                             0, imageData.length, opts);
 
-                    compareRegionByRegion(decoder, opts, wholeImage);
+                    if (RES_IDS[i] == R.drawable.webp_test && COLOR_CONFIGS[k] == Config.RGB_565) {
+                        compareRegionByRegion(decoder, opts, mMseMarginWebPConfigRgb565,
+                                              wholeImage);
+                    } else {
+                        compareRegionByRegion(decoder, opts, mMseMargin, wholeImage);
+                    }
                     wholeImage.recycle();
                 }
             }
@@ -245,14 +259,24 @@
                     BitmapRegionDecoder decoder =
                         BitmapRegionDecoder.newInstance(filepath, false);
                     Bitmap wholeImage = BitmapFactory.decodeFile(filepath, opts);
-                    compareRegionByRegion(decoder, opts, wholeImage);
+                    if (RES_IDS[i] == R.drawable.webp_test && COLOR_CONFIGS[k] == Config.RGB_565) {
+                        compareRegionByRegion(decoder, opts, mMseMarginWebPConfigRgb565,
+                                              wholeImage);
+                    } else {
+                        compareRegionByRegion(decoder, opts, mMseMargin, wholeImage);
+                    }
 
                     ParcelFileDescriptor pfd1 = obtainParcelDescriptor(filepath);
                     FileDescriptor fd1 = pfd1.getFileDescriptor();
                     decoder = BitmapRegionDecoder.newInstance(fd1, false);
                     ParcelFileDescriptor pfd2 = obtainParcelDescriptor(filepath);
                     FileDescriptor fd2 = pfd2.getFileDescriptor();
-                    compareRegionByRegion(decoder, opts, wholeImage);
+                    if (RES_IDS[i] == R.drawable.webp_test && COLOR_CONFIGS[k] == Config.RGB_565) {
+                        compareRegionByRegion(decoder, opts, mMseMarginWebPConfigRgb565,
+                                              wholeImage);
+                    } else {
+                        compareRegionByRegion(decoder, opts, mMseMargin, wholeImage);
+                    }
                     wholeImage.recycle();
                 }
             }
@@ -298,7 +322,7 @@
     }
 
     private void compareRegionByRegion(BitmapRegionDecoder decoder,
-            Options opts, Bitmap wholeImage) {
+            Options opts, int mseMargin, Bitmap wholeImage) {
         int width = decoder.getWidth();
         int height = decoder.getHeight();
         Rect rect = new Rect(0, 0, width, height);
@@ -318,7 +342,7 @@
                 Rect rect2 = new Rect(left, top, left + actual.getWidth(),
                         top + actual.getHeight());
                 expected = cropBitmap(wholeImage, rect2);
-                compareBitmaps(expected, actual, mMseMargin, true);
+                compareBitmaps(expected, actual, mseMargin, true);
                 actual.recycle();
                 expected.recycle();
             }