From 237eab6764722adb00643c981802eb4be10b2bbe Mon Sep 17 00:00:00 2001 From: Vikas Arora Date: Wed, 23 May 2012 12:08:44 +0530 Subject: [PATCH] Add two more color-spaces for lossless decoding. Added color-spaces (RGBA_4444 and RGB_565), required for Android device to lossless decoding. Change-Id: I229832edd4deca59e066f463e7454f77457c5bcd --- src/dec/vp8l.c | 4 ++-- src/dsp/lossless.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/dec/vp8l.c b/src/dec/vp8l.c index 63b0d8b1..148dac40 100644 --- a/src/dec/vp8l.c +++ b/src/dec/vp8l.c @@ -946,8 +946,8 @@ int VP8LDecodeImage(VP8LDecoder* const dec) { params = (WebPDecParams*)io->opaque; assert(params != NULL); output = params->output; - // RGBA_4444 & RGB_565 are unsupported for now & YUV modes are invalid. - if (output->colorspace >= MODE_RGBA_4444) { + // YUV modes are invalid. + if (output->colorspace >= MODE_YUV) { dec->status_ = VP8_STATUS_INVALID_PARAM; goto Err; } diff --git a/src/dsp/lossless.c b/src/dsp/lossless.c index f40c698c..42576a0f 100644 --- a/src/dsp/lossless.c +++ b/src/dsp/lossless.c @@ -966,7 +966,7 @@ static int is_big_endian(void) { static void ConvertBGRAToRGB(const uint32_t* src, int num_pixels, uint8_t* dst) { - const uint32_t* src_end = src + num_pixels; + const uint32_t* const src_end = src + num_pixels; while (src < src_end) { const uint32_t argb = *src++; *dst++ = (argb >> 16) & 0xff; @@ -977,7 +977,7 @@ static void ConvertBGRAToRGB(const uint32_t* src, static void ConvertBGRAToRGBA(const uint32_t* src, int num_pixels, uint8_t* dst) { - const uint32_t* src_end = src + num_pixels; + const uint32_t* const src_end = src + num_pixels; while (src < src_end) { const uint32_t argb = *src++; *dst++ = (argb >> 16) & 0xff; @@ -987,9 +987,29 @@ static void ConvertBGRAToRGBA(const uint32_t* src, } } +static void ConvertBGRAToRGBA4444(const uint32_t* src, + int num_pixels, uint8_t* dst) { + const uint32_t* const src_end = src + num_pixels; + while (src < src_end) { + const uint32_t argb = *src++; + *dst++ = ((argb >> 16) & 0xf0) | ((argb >> 12) & 0xf); + *dst++ = ((argb >> 0) & 0xf0) | ((argb >> 28) & 0xf); + } +} + +static void ConvertBGRAToRGB565(const uint32_t* src, + int num_pixels, uint8_t* dst) { + const uint32_t* const src_end = src + num_pixels; + while (src < src_end) { + const uint32_t argb = *src++; + *dst++ = ((argb >> 16) & 0xf8) | ((argb >> 13) & 0x7); + *dst++ = ((argb >> 5) & 0xe0) | ((argb >> 3) & 0x1f); + } +} + static void ConvertBGRAToBGR(const uint32_t* src, int num_pixels, uint8_t* dst) { - const uint32_t* src_end = src + num_pixels; + const uint32_t* const src_end = src + num_pixels; while (src < src_end) { const uint32_t argb = *src++; *dst++ = (argb >> 0) & 0xff; @@ -1001,7 +1021,7 @@ static void ConvertBGRAToBGR(const uint32_t* src, static void CopyOrSwap(const uint32_t* src, int num_pixels, uint8_t* dst, int swap_on_big_endian) { if (is_big_endian() == swap_on_big_endian) { - const uint32_t* src_end = src + num_pixels; + const uint32_t* const src_end = src + num_pixels; while (src < src_end) { uint32_t argb = *src++; #if !defined(__BIG_ENDIAN__) && (defined(__i386__) || defined(__x86_64__)) @@ -1043,6 +1063,12 @@ void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels, case MODE_ARGB: CopyOrSwap(in_data, num_pixels, rgba, 0); break; + case MODE_RGBA_4444: + ConvertBGRAToRGBA4444(in_data, num_pixels, rgba); + break; + case MODE_RGB_565: + ConvertBGRAToRGB565(in_data, num_pixels, rgba); + break; default: assert(0); // Code flow should not reach here. }