From 94a48b4bc39b50ffde2ed92661d882f697bd62bf Mon Sep 17 00:00:00 2001 From: Vikas Arora Date: Fri, 18 Jan 2013 16:23:09 -0800 Subject: [PATCH] Provide option to swap bytes for 16 bit colormodes Color modes: RGB_565 & RGBA_4444 Change-Id: I571b6832b9848e5c4109272978f68623ca373383 --- configure.ac | 13 +++++++++++++ makefile.unix | 3 +++ src/dsp/Makefile.am | 2 +- src/dsp/lossless.c | 22 ++++++++++++++++++---- src/dsp/yuv.h | 29 +++++++++++++++++++++-------- src/webp/decode.h | 9 ++++++++- 6 files changed, 64 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index a8b12e73..bf09d330 100644 --- a/configure.ac +++ b/configure.ac @@ -226,6 +226,19 @@ if test "$target_os" = "mingw32"; then fi fi +dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP + +USE_SWAP_16BIT_CSP="" +AC_MSG_CHECKING(if --enable-swap-16bit-csp option is specified) +AC_ARG_ENABLE([swap-16bit-csp], + AS_HELP_STRING([--enable-swap-16bit-csp], + [Enable byte swap for 16 bit colorspaces])) +if test "$enable_swap_16bit_csp" = "yes"; then + USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP" +fi +AC_MSG_RESULT(${enable_swap_16bit_csp-no}) +AC_SUBST(USE_SWAP_16BIT_CSP) + dnl === If --enable-experimental is defined, add -DWEBP_EXPERIMENTAL_FEATURES USE_EXPERIMENTAL_CODE="" diff --git a/makefile.unix b/makefile.unix index b027786f..23e811f6 100644 --- a/makefile.unix +++ b/makefile.unix @@ -53,6 +53,9 @@ endif # Extra flags to enable experimental features and code # EXTRA_FLAGS += -DWEBP_EXPERIMENTAL_FEATURES +# Extra flags to enable byte swap for 16 bit colorspaces. +# EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP + # Extra flags to enable multi-threading EXTRA_FLAGS += -DWEBP_USE_THREAD EXTRA_LIBS += -lpthread diff --git a/src/dsp/Makefile.am b/src/dsp/Makefile.am index 792ef0ef..e28e3e08 100644 --- a/src/dsp/Makefile.am +++ b/src/dsp/Makefile.am @@ -23,5 +23,5 @@ noinst_HEADERS += ../dec/decode_vp8.h noinst_HEADERS += ../webp/decode.h libwebpdsp_la_LDFLAGS = -lm -libwebpdsp_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) +libwebpdsp_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) $(USE_SWAP_16BIT_CSP) libwebpdspincludedir = $(includedir)/webp diff --git a/src/dsp/lossless.c b/src/dsp/lossless.c index 945cc8b7..f951b897 100644 --- a/src/dsp/lossless.c +++ b/src/dsp/lossless.c @@ -1033,8 +1033,15 @@ static void ConvertBGRAToRGBA4444(const uint32_t* src, 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); + const uint8_t rg = ((argb >> 16) & 0xf0) | ((argb >> 12) & 0xf); + const uint8_t ba = ((argb >> 0) & 0xf0) | ((argb >> 28) & 0xf); +#ifdef WEBP_SWAP_16BIT_CSP + *dst++ = ba; + *dst++ = rg; +#else + *dst++ = rg; + *dst++ = ba; +#endif } } @@ -1043,8 +1050,15 @@ static void ConvertBGRAToRGB565(const uint32_t* src, 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); + const uint8_t rg = ((argb >> 16) & 0xf8) | ((argb >> 13) & 0x7); + const uint8_t gb = ((argb >> 5) & 0xe0) | ((argb >> 3) & 0x1f); +#ifdef WEBP_SWAP_16BIT_CSP + *dst++ = gb; + *dst++ = rg; +#else + *dst++ = rg; + *dst++ = gb; +#endif } } diff --git a/src/dsp/yuv.h b/src/dsp/yuv.h index ace4ce03..b3713690 100644 --- a/src/dsp/yuv.h +++ b/src/dsp/yuv.h @@ -62,10 +62,17 @@ static WEBP_INLINE void VP8YuvToRgb565(uint8_t y, uint8_t u, uint8_t v, const int r_off = VP8kVToR[v]; const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX; const int b_off = VP8kUToB[u]; - rgb[0] = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) | - (VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5)); - rgb[1] = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) | - (VP8kClip[y + b_off - YUV_RANGE_MIN] >> 3)); + const uint8_t rg = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) | + (VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5)); + const uint8_t gb = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) | + (VP8kClip[y + b_off - YUV_RANGE_MIN] >> 3)); +#ifdef WEBP_SWAP_16BIT_CSP + rgb[0] = gb; + rgb[1] = rg; +#else + rgb[0] = rg; + rgb[1] = gb; +#endif } static WEBP_INLINE void VP8YuvToArgb(uint8_t y, uint8_t u, uint8_t v, @@ -79,10 +86,16 @@ static WEBP_INLINE void VP8YuvToRgba4444(uint8_t y, uint8_t u, uint8_t v, const int r_off = VP8kVToR[v]; const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX; const int b_off = VP8kUToB[u]; - // Don't update alpha (last 4 bits of argb[1]) - argb[0] = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) | - VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]); - argb[1] = 0x0f | (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4); + const uint8_t rg = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) | + VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]); + const uint8_t ba = (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4) | 0x0f; +#ifdef WEBP_SWAP_16BIT_CSP + argb[0] = ba; + argb[1] = rg; +#else + argb[0] = rg; + argb[1] = ba; +#endif } static WEBP_INLINE void VP8YuvToBgr(uint8_t y, uint8_t u, uint8_t v, diff --git a/src/webp/decode.h b/src/webp/decode.h index b24af382..aabeae0f 100644 --- a/src/webp/decode.h +++ b/src/webp/decode.h @@ -130,7 +130,14 @@ WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto( // Note: the naming describes the byte-ordering of packed samples in memory. // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,... // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels. -// RGB-565 and RGBA-4444 are also endian-agnostic and byte-oriented. +// RGBA-4444 and RGB-565 colorspaces are represented by following byte-order: +// RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ... +// RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ... +// In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for +// these two modes: +// RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ... +// RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ... + enum WEBP_CSP_MODE { MODE_RGB = 0, MODE_RGBA = 1, MODE_BGR = 2, MODE_BGRA = 3,