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();
}