From af74c1453b74380323c86e54fe0d89a113d0055f Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Wed, 15 Apr 2015 02:14:08 -0700 Subject: [PATCH] populate 'libwebpextras' with: import gray, rgb565 and rgb4444 functions update makefile.unix to provide 'make extras' building instructions. note: input ordering depends on WEBP_SWAP_16BIT_CSP for rgb565 and rgb4444 Change-Id: I6f22d32189d9ba2619146a9714cedabfe28e2ad0 --- makefile.unix | 11 ++++-- src/extras/extras.c | 88 +++++++++++++++++++++++++++++++++++++++++++++ src/webp/extras.h | 17 +++++++++ 3 files changed, 114 insertions(+), 2 deletions(-) diff --git a/makefile.unix b/makefile.unix index 49c98565..8a39f0d5 100644 --- a/makefile.unix +++ b/makefile.unix @@ -2,8 +2,8 @@ # system, for simple local building of the libraries and tools. # It will not install the libraries system-wide, but just create the 'cwebp' # and 'dwebp' tools in the examples/ directory, along with the static -# libraries 'src/libwebp.a', 'src/libwebpdecoder.a', 'src/mux/libwebpmux.a' and -# 'src/demux/libwebpdemux.a'. +# libraries 'src/libwebp.a', 'src/libwebpdecoder.a', 'src/mux/libwebpmux.a', +# 'src/demux/libwebpdemux.a' and 'src/libwebpextras.a'. # # To build the library and examples, use: # make -f makefile.unix @@ -224,11 +224,15 @@ UTILS_ENC_OBJS = \ src/utils/huffman_encode.o \ src/utils/quant_levels.o \ +EXTRA_OBJS = \ + src/extras/extras.o \ + LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS) LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \ $(UTILS_ENC_OBJS) LIBWEBPMUX_OBJS = $(MUX_OBJS) LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) +LIBWEBPEXTRA_OBJS = $(EXTRA_OBJS) HDRS_INSTALLED = \ src/webp/decode.h \ @@ -275,6 +279,7 @@ HDRS = \ $(HDRS_INSTALLED) \ OUT_LIBS = examples/libexample_util.a src/libwebpdecoder.a src/libwebp.a +EXTRA_LIB = src/libwebpextras.a OUT_EXAMPLES = examples/cwebp examples/dwebp EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux @@ -287,6 +292,7 @@ endif ex: $(OUT_EXAMPLES) all: ex $(EXTRA_EXAMPLES) +extras: $(EXTRA_LIB) $(EX_FORMAT_DEC_OBJS): %.o: %.h @@ -307,6 +313,7 @@ src/libwebpdecoder.a: $(LIBWEBPDECODER_OBJS) src/libwebp.a: $(LIBWEBP_OBJS) src/mux/libwebpmux.a: $(LIBWEBPMUX_OBJS) src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS) +src/libwebpextras.a: $(LIBWEBPEXTRA_OBJS) %.a: $(AR) $(ARFLAGS) $@ $^ diff --git a/src/extras/extras.c b/src/extras/extras.c index 63a38c05..ca32fbcd 100644 --- a/src/extras/extras.c +++ b/src/extras/extras.c @@ -12,6 +12,8 @@ #include "../webp/extras.h" +#include + #define XTRA_MAJ_VERSION 0 #define XTRA_MIN_VERSION 0 #define XTRA_REV_VERSION 0 @@ -21,3 +23,89 @@ int WebPGetExtrasVersion(void) { return (XTRA_MAJ_VERSION << 16) | (XTRA_MIN_VERSION << 8) | XTRA_REV_VERSION; } + +//------------------------------------------------------------------------------ + +int WebPImportGray(const uint8_t* gray_data, WebPPicture* pic) { + int y, width, uv_width; + if (pic == NULL || gray_data == NULL) return 0; + pic->colorspace = WEBP_YUV420; + if (!WebPPictureAlloc(pic)) return 0; + width = pic->width; + uv_width = (width + 1) >> 1; + for (y = 0; y < pic->height; ++y) { + memcpy(pic->y + y * pic->y_stride, gray_data, width); + gray_data += width; // <- we could use some 'data_stride' here if needed + if ((y & 1) == 0) { + memset(pic->u + (y >> 1) * pic->uv_stride, 128, uv_width); + memset(pic->v + (y >> 1) * pic->uv_stride, 128, uv_width); + } + } + return 1; +} + +int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) { + int x, y; + if (pic == NULL || rgb565 == NULL) return 0; + pic->colorspace = WEBP_YUV420; + pic->use_argb = 1; + if (!WebPPictureAlloc(pic)) return 0; + for (y = 0; y < pic->height; ++y) { + const int width = pic->width; + uint32_t* dst = pic->argb + y * pic->argb_stride; + for (x = 0; x < width; ++x) { +#ifdef WEBP_SWAP_16BIT_CSP + const uint32_t rg = rgb565[2 * x + 1]; + const uint32_t gb = rgb565[2 * x + 0]; +#else + const uint32_t rg = rgb565[2 * x + 0]; + const uint32_t gb = rgb565[2 * x + 1]; +#endif + uint32_t r = rg & 0xf8; + uint32_t g = ((rg << 5) | (gb >> 3)) & 0xfc; + uint32_t b = (gb << 5); + // dithering + r = r | (r >> 5); + g = g | (g >> 6); + b = b | (b >> 5); + dst[x] = (r << 16) | (g << 8) | b; + } + rgb565 += 2 * width; + } + return 1; +} + +int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) { + int x, y; + if (pic == NULL || rgb4444 == NULL) return 0; + pic->colorspace = WEBP_YUV420; + pic->use_argb = 1; + if (!WebPPictureAlloc(pic)) return 0; + for (y = 0; y < pic->height; ++y) { + const int width = pic->width; + uint32_t* dst = pic->argb + y * pic->argb_stride; + for (x = 0; x < width; ++x) { +#ifdef WEBP_SWAP_16BIT_CSP + const uint32_t rg = rgb4444[2 * x + 1]; + const uint32_t ba = rgb4444[2 * x + 0]; +#else + const uint32_t rg = rgb4444[2 * x + 0]; + const uint32_t ba = rgb4444[2 * x + 1]; +#endif + uint32_t r = rg & 0xf0; + uint32_t g = (rg << 4); + uint32_t b = (ba & 0xf0); + uint32_t a = (ba << 4); + // dithering + r = r | (r >> 4); + g = g | (g >> 4); + b = b | (b >> 4); + a = a | (a >> 4); + dst[x] = (a << 24) | (r << 16) | (g << 8) | b; + } + rgb4444 += 2 * width; + } + return 1; +} + +//------------------------------------------------------------------------------ diff --git a/src/webp/extras.h b/src/webp/extras.h index b62cd582..1c24be2e 100644 --- a/src/webp/extras.h +++ b/src/webp/extras.h @@ -17,6 +17,8 @@ extern "C" { #endif +#include "./encode.h" + #define WEBP_EXTRAS_ABI_VERSION 0x0000 // MAJOR(8b) + MINOR(8b) //------------------------------------------------------------------------------ @@ -25,6 +27,21 @@ extern "C" { // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. WEBP_EXTERN(int) WebPGetExtrasVersion(void); +//------------------------------------------------------------------------------ +// Ad-hoc colorspace importers. + +// Import luma sample (gray scale image) into 'picture'. The 'picture' +// width and height must be set prior to calling this function. +WEBP_EXTERN(int) WebPImportGray(const uint8_t* gray, WebPPicture* picture); + +// Import rgb sample in RGB565 packed format into 'picture'. The 'picture' +// width and height must be set prior to calling this function. +WEBP_EXTERN(int) WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic); + +// Import rgb sample in RGB4444 packed format into 'picture'. The 'picture' +// width and height must be set prior to calling this function. +WEBP_EXTERN(int) WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic); + //------------------------------------------------------------------------------ #ifdef __cplusplus