aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRagesh Radhakrishnan <ragesh.r@linaro.org>2013-12-03 10:05:01 +0530
committerRagesh Radhakrishnan <ragesh.r@linaro.org>2013-12-03 10:05:01 +0530
commitb8e0c4693e40586e4db2c7c6e462c6c3d41bad49 (patch)
tree78a5c1eecbdfc9325087e2b1fe06b7fd8708eb1e
parent337a5f8b00da8767dc699425b10a72ab5473bb51 (diff)
Added Android specific RGB colorspace conversions
RGBA8888 integrated with existing jsimd_rgb_grey_convert. Added h2v1 and h2v2 upscalling functions with neon acceleraiton.
-rw-r--r--simd/jsimd_arm.c134
1 files changed, 133 insertions, 1 deletions
diff --git a/simd/jsimd_arm.c b/simd/jsimd_arm.c
index cae84df..b395310 100644
--- a/simd/jsimd_arm.c
+++ b/simd/jsimd_arm.c
@@ -27,6 +27,40 @@
#include <string.h>
#include <ctype.h>
+typedef JMETHOD(void, upsample1_ptr,
+ (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+typedef struct {
+ struct jpeg_upsampler pub; /* public fields */
+
+ /* Color conversion buffer. When using separate upsampling and color
+ * conversion steps, this buffer holds one upsampled row group until it
+ * has been color converted and output.
+ * Note: we do not allocate any storage for component(s) which are full-size,
+ * ie do not need rescaling. The corresponding entry of color_buf[] is
+ * simply set to point to the input data array, thereby avoiding copying.
+ */
+ JSAMPARRAY color_buf[MAX_COMPONENTS];
+
+ /* Per-component upsampling method pointers */
+ upsample1_ptr methods[MAX_COMPONENTS];
+
+ int next_row_out; /* counts rows emitted from color_buf */
+ JDIMENSION rows_to_go; /* counts rows remaining in image */
+
+ /* Height of an input row group for each component. */
+ int rowgroup_height[MAX_COMPONENTS];
+
+ /* These arrays save pixel expansion factors so that int_expand need not
+ * recompute them each time. They are unused for other upsampling methods.
+ */
+ UINT8 h_expand[MAX_COMPONENTS];
+ UINT8 v_expand[MAX_COMPONENTS];
+} my_upsampler;
+
+typedef my_upsampler * my_upsample_ptr;
+
static unsigned int simd_support = ~0;
#if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
@@ -176,6 +210,24 @@ jsimd_can_ycc_rgb (void)
return 0;
}
+GLOBAL(int)
+jsimd_can_ycc_android_rgb (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (BITS_IN_JSAMPLE != 8)
+ return 0;
+ if (sizeof(JDIMENSION) != 4)
+ return 0;
+ if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
+ return 0;
+ if (simd_support & JSIMD_ARM_NEON)
+ return 1;
+
+ return 0;
+}
+
GLOBAL(void)
jsimd_rgb_ycc_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
@@ -238,7 +290,10 @@ jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
break;
case JCS_EXT_RGBX:
case JCS_EXT_RGBA:
- neonfct=jsimd_ycc_extrgbx_convert_neon;
+ #ifdef ANDROID_RGB
+ case JCS_RGBA_8888:
+ #endif
+ neonfct=jsimd_ycc_extrgbx_convert_neon;
break;
case JCS_EXT_BGR:
neonfct=jsimd_ycc_extbgr_convert_neon;
@@ -374,7 +429,11 @@ jsimd_can_h2v2_merged_upsample (void)
{
init_simd();
+#ifdef ANDROID_JPEG_USE_VENUM
+ return 1;
+#else
return 0;
+#endif
}
GLOBAL(int)
@@ -382,7 +441,12 @@ jsimd_can_h2v1_merged_upsample (void)
{
init_simd();
+
+#ifdef ANDROID_JPEG_USE_VENUM
+ return 1;
+#else
return 0;
+#endif
}
GLOBAL(void)
@@ -391,6 +455,46 @@ jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo,
JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf)
{
+#ifdef ANDROID_JPEG_USE_VENUM
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ JSAMPROW outptr0, outptr1;
+ JSAMPROW inptr00, inptr01, inptr1, inptr2;
+ inptr00 = input_buf[0][in_row_group_ctr*2];
+ inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
+ inptr1 = input_buf[1][in_row_group_ctr];
+ inptr2 = input_buf[2][in_row_group_ctr];
+ outptr0 = output_buf[0];
+ outptr1 = output_buf[1];
+
+#ifdef ANDROID_RGB
+ if (cinfo->out_color_space == JCS_RGBA_8888) {
+ yyvup2abgr8888_venum((UINT8*) inptr00,
+ (UINT8*) inptr2,
+ (UINT8*) inptr1,
+ (UINT8*) outptr0,
+ cinfo->output_width);
+ yyvup2abgr8888_venum((UINT8*) inptr01,
+ (UINT8*) inptr2,
+ (UINT8*) inptr1,
+ (UINT8*) outptr1,
+ cinfo->output_width);
+ } else
+#endif
+ {
+ yyvup2bgr888_venum((UINT8*) inptr00,
+ (UINT8*) inptr2,
+ (UINT8*) inptr1,
+ (UINT8*) outptr0,
+ cinfo->output_width);
+
+ yyvup2bgr888_venum((UINT8*) inptr01,
+ (UINT8*) inptr2,
+ (UINT8*) inptr1,
+ (UINT8*) outptr1,
+ cinfo->output_width);
+ }
+
+#endif
}
GLOBAL(void)
@@ -399,6 +503,34 @@ jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo,
JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf)
{
+#ifdef ANDROID_JPEG_USE_VENUM
+
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ JSAMPROW inptr0, inptr1, inptr2;
+ JSAMPROW outptr;
+
+ inptr0 = input_buf[0][in_row_group_ctr];
+ inptr1 = input_buf[1][in_row_group_ctr];
+ inptr2 = input_buf[2][in_row_group_ctr];
+ outptr = output_buf[0];
+
+#ifdef ANDROID_RGB
+ if (cinfo->out_color_space == JCS_RGBA_8888) {
+ yyvup2abgr8888_venum((UINT8*) inptr0,
+ (UINT8*) inptr2,
+ (UINT8*) inptr1,
+ (UINT8*) outptr,
+ cinfo->output_width);
+ } else
+#endif
+ {
+ yyvup2bgr888_venum((UINT8*) inptr0,
+ (UINT8*) inptr2,
+ (UINT8*) inptr1,
+ (UINT8*) outptr,
+ cinfo->output_width);
+ }
+#endif
}
GLOBAL(int)