Provide option to swap bytes for 16 bit colormodes

Color modes: RGB_565 & RGBA_4444
Change-Id: I571b6832b9848e5c4109272978f68623ca373383
This commit is contained in:
Vikas Arora 2013-01-18 16:23:09 -08:00
parent 1d2702b1da
commit 94a48b4bc3
6 changed files with 64 additions and 14 deletions

View File

@ -226,6 +226,19 @@ if test "$target_os" = "mingw32"; then
fi fi
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 dnl === If --enable-experimental is defined, add -DWEBP_EXPERIMENTAL_FEATURES
USE_EXPERIMENTAL_CODE="" USE_EXPERIMENTAL_CODE=""

View File

@ -53,6 +53,9 @@ endif
# Extra flags to enable experimental features and code # Extra flags to enable experimental features and code
# EXTRA_FLAGS += -DWEBP_EXPERIMENTAL_FEATURES # 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 to enable multi-threading
EXTRA_FLAGS += -DWEBP_USE_THREAD EXTRA_FLAGS += -DWEBP_USE_THREAD
EXTRA_LIBS += -lpthread EXTRA_LIBS += -lpthread

View File

@ -23,5 +23,5 @@ noinst_HEADERS += ../dec/decode_vp8.h
noinst_HEADERS += ../webp/decode.h noinst_HEADERS += ../webp/decode.h
libwebpdsp_la_LDFLAGS = -lm libwebpdsp_la_LDFLAGS = -lm
libwebpdsp_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) libwebpdsp_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE) $(USE_SWAP_16BIT_CSP)
libwebpdspincludedir = $(includedir)/webp libwebpdspincludedir = $(includedir)/webp

View File

@ -1033,8 +1033,15 @@ static void ConvertBGRAToRGBA4444(const uint32_t* src,
const uint32_t* const src_end = src + num_pixels; const uint32_t* const src_end = src + num_pixels;
while (src < src_end) { while (src < src_end) {
const uint32_t argb = *src++; const uint32_t argb = *src++;
*dst++ = ((argb >> 16) & 0xf0) | ((argb >> 12) & 0xf); const uint8_t rg = ((argb >> 16) & 0xf0) | ((argb >> 12) & 0xf);
*dst++ = ((argb >> 0) & 0xf0) | ((argb >> 28) & 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; const uint32_t* const src_end = src + num_pixels;
while (src < src_end) { while (src < src_end) {
const uint32_t argb = *src++; const uint32_t argb = *src++;
*dst++ = ((argb >> 16) & 0xf8) | ((argb >> 13) & 0x7); const uint8_t rg = ((argb >> 16) & 0xf8) | ((argb >> 13) & 0x7);
*dst++ = ((argb >> 5) & 0xe0) | ((argb >> 3) & 0x1f); 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
} }
} }

View File

@ -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 r_off = VP8kVToR[v];
const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX; const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
const int b_off = VP8kUToB[u]; const int b_off = VP8kUToB[u];
rgb[0] = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) | const uint8_t rg = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) |
(VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5)); (VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5));
rgb[1] = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) | const uint8_t gb = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) |
(VP8kClip[y + b_off - YUV_RANGE_MIN] >> 3)); (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, 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 r_off = VP8kVToR[v];
const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX; const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
const int b_off = VP8kUToB[u]; const int b_off = VP8kUToB[u];
// Don't update alpha (last 4 bits of argb[1]) const uint8_t rg = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) |
argb[0] = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) | VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]);
VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]); const uint8_t ba = (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4) | 0x0f;
argb[1] = 0x0f | (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4); #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, static WEBP_INLINE void VP8YuvToBgr(uint8_t y, uint8_t u, uint8_t v,

View File

@ -130,7 +130,14 @@ WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto(
// Note: the naming describes the byte-ordering of packed samples in memory. // 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,... // 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. // 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 { enum WEBP_CSP_MODE {
MODE_RGB = 0, MODE_RGBA = 1, MODE_RGB = 0, MODE_RGBA = 1,
MODE_BGR = 2, MODE_BGRA = 3, MODE_BGR = 2, MODE_BGRA = 3,