mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
add support for RGB565, ARGB4444 and ARGB colorspace (decoder)
RGB565 and ARGB4444 are only supported through the advanced decoding API. ARGB being somewhat generic, there's an easy WebPDecodeARGB() new function for convenience. Patch by Vikas Arora (vikaas dot arora at gmail dot com) Change-Id: Ic7b6f72bd70aca458d14e7fdd23679212430ebca
This commit is contained in:
parent
c915fb2aa7
commit
19db59f80f
@ -20,6 +20,9 @@ extern "C" {
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// WebPDecBuffer
|
// WebPDecBuffer
|
||||||
|
|
||||||
|
// Number of bytes per pixel for the different color-spaces.
|
||||||
|
static const int kModeBpp[MODE_LAST] = { 3, 4, 3, 4, 4, 2, 2, 1, 1 };
|
||||||
|
|
||||||
static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
WEBP_CSP_MODE mode = buffer->colorspace;
|
WEBP_CSP_MODE mode = buffer->colorspace;
|
||||||
@ -44,11 +47,7 @@ static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
|||||||
} else { // RGB checks
|
} else { // RGB checks
|
||||||
const WebPRGBABuffer* const buf = &buffer->u.RGBA;
|
const WebPRGBABuffer* const buf = &buffer->u.RGBA;
|
||||||
ok &= (buf->stride * height <= buf->size);
|
ok &= (buf->stride * height <= buf->size);
|
||||||
if (mode == MODE_RGB || mode == MODE_BGR) {
|
ok &= (buf->stride >= width * kModeBpp[mode]);
|
||||||
ok &= (buf->stride >= width * 3);
|
|
||||||
} else if (mode == MODE_RGBA || mode == MODE_BGRA) {
|
|
||||||
ok &= (buf->stride >= width * 4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ok ? VP8_STATUS_OK : VP8_STATUS_INVALID_PARAM;
|
return ok ? VP8_STATUS_OK : VP8_STATUS_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
@ -70,9 +69,7 @@ static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
|
|||||||
uint64_t size, a_size = 0, total_size;
|
uint64_t size, a_size = 0, total_size;
|
||||||
// We need memory and it hasn't been allocated yet.
|
// We need memory and it hasn't been allocated yet.
|
||||||
// => initialize output buffer, now that dimensions are known.
|
// => initialize output buffer, now that dimensions are known.
|
||||||
stride = (mode == MODE_RGB || mode == MODE_BGR) ? 3 * w
|
stride = w * kModeBpp[mode];
|
||||||
: (mode == MODE_RGBA || mode == MODE_BGRA) ? 4 * w
|
|
||||||
: w;
|
|
||||||
size = (uint64_t)stride * h;
|
size = (uint64_t)stride * h;
|
||||||
|
|
||||||
if (mode >= MODE_YUV) {
|
if (mode >= MODE_YUV) {
|
||||||
|
49
src/dec/io.c
49
src/dec/io.c
@ -21,9 +21,6 @@ extern "C" {
|
|||||||
|
|
||||||
#define FANCY_UPSAMPLING // undefined to remove fancy upsampling support
|
#define FANCY_UPSAMPLING // undefined to remove fancy upsampling support
|
||||||
|
|
||||||
// mask to apply to WEBP_CSP_MODE, to know if there's alpha channel or not.
|
|
||||||
#define MODE_ALPHA_MASK 1
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Fancy upsampler
|
// Fancy upsampler
|
||||||
|
|
||||||
@ -101,27 +98,38 @@ UPSAMPLE_FUNC(UpsampleRgbLinePair, VP8YuvToRgb, 3)
|
|||||||
UPSAMPLE_FUNC(UpsampleBgrLinePair, VP8YuvToBgr, 3)
|
UPSAMPLE_FUNC(UpsampleBgrLinePair, VP8YuvToBgr, 3)
|
||||||
UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4)
|
UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4)
|
||||||
UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4)
|
UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4)
|
||||||
|
UPSAMPLE_FUNC(UpsampleArgbLinePair, VP8YuvToArgb, 4)
|
||||||
|
UPSAMPLE_FUNC(UpsampleArgb4444LinePair, VP8YuvToArgb4444, 2)
|
||||||
|
UPSAMPLE_FUNC(UpsampleRgb565LinePair, VP8YuvToRgb565, 2)
|
||||||
// These two don't erase the alpha value
|
// These two don't erase the alpha value
|
||||||
UPSAMPLE_FUNC(UpsampleRgbKeepAlphaLinePair, VP8YuvToRgb, 4)
|
UPSAMPLE_FUNC(UpsampleRgbKeepAlphaLinePair, VP8YuvToRgb, 4)
|
||||||
UPSAMPLE_FUNC(UpsampleBgrKeepAlphaLinePair, VP8YuvToBgr, 4)
|
UPSAMPLE_FUNC(UpsampleBgrKeepAlphaLinePair, VP8YuvToBgr, 4)
|
||||||
|
UPSAMPLE_FUNC(UpsampleArgbKeepAlphaLinePair, VP8YuvToArgbKeepA, 4)
|
||||||
|
UPSAMPLE_FUNC(UpsampleArgb4444KeepAlphaLinePair, VP8YuvToArgb4444KeepA, 2)
|
||||||
|
|
||||||
#undef LOAD_UV
|
#undef LOAD_UV
|
||||||
#undef UPSAMPLE_FUNC
|
#undef UPSAMPLE_FUNC
|
||||||
|
|
||||||
// Fancy upsampling functions to convert YUV to RGB
|
// Fancy upsampling functions to convert YUV to RGB
|
||||||
WebPUpsampleLinePairFunc WebPUpsamplers[MODE_BGRA + 1];
|
WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST];
|
||||||
WebPUpsampleLinePairFunc WebPUpsamplersKeepAlpha[MODE_BGRA + 1];
|
WebPUpsampleLinePairFunc WebPUpsamplersKeepAlpha[MODE_LAST];
|
||||||
|
|
||||||
static void InitUpsamplers(void) {
|
static void InitUpsamplers(void) {
|
||||||
WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePair;
|
WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePair;
|
||||||
WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair;
|
WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair;
|
||||||
WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePair;
|
WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePair;
|
||||||
WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair;
|
WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair;
|
||||||
|
WebPUpsamplers[MODE_ARGB] = UpsampleArgbLinePair;
|
||||||
|
WebPUpsamplers[MODE_ARGB_4444] = UpsampleArgb4444LinePair;
|
||||||
|
WebPUpsamplers[MODE_RGB_565] = UpsampleRgb565LinePair;
|
||||||
|
|
||||||
WebPUpsamplersKeepAlpha[MODE_RGB] = UpsampleRgbLinePair;
|
WebPUpsamplersKeepAlpha[MODE_RGB] = UpsampleRgbLinePair;
|
||||||
WebPUpsamplersKeepAlpha[MODE_RGBA] = UpsampleRgbKeepAlphaLinePair;
|
WebPUpsamplersKeepAlpha[MODE_RGBA] = UpsampleRgbKeepAlphaLinePair;
|
||||||
WebPUpsamplersKeepAlpha[MODE_BGR] = UpsampleBgrLinePair;
|
WebPUpsamplersKeepAlpha[MODE_BGR] = UpsampleBgrLinePair;
|
||||||
WebPUpsamplersKeepAlpha[MODE_BGRA] = UpsampleBgrKeepAlphaLinePair;
|
WebPUpsamplersKeepAlpha[MODE_BGRA] = UpsampleBgrKeepAlphaLinePair;
|
||||||
|
WebPUpsamplersKeepAlpha[MODE_ARGB] = UpsampleArgbKeepAlphaLinePair;
|
||||||
|
WebPUpsamplersKeepAlpha[MODE_ARGB_4444] = UpsampleArgb4444KeepAlphaLinePair;
|
||||||
|
WebPUpsamplersKeepAlpha[MODE_RGB_565] = UpsampleRgb565LinePair;
|
||||||
|
|
||||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8DecGetCPUInfo) {
|
if (VP8DecGetCPUInfo) {
|
||||||
@ -166,6 +174,9 @@ SAMPLE_FUNC(SampleRgbLinePair, VP8YuvToRgb, 3)
|
|||||||
SAMPLE_FUNC(SampleBgrLinePair, VP8YuvToBgr, 3)
|
SAMPLE_FUNC(SampleBgrLinePair, VP8YuvToBgr, 3)
|
||||||
SAMPLE_FUNC(SampleRgbaLinePair, VP8YuvToRgba, 4)
|
SAMPLE_FUNC(SampleRgbaLinePair, VP8YuvToRgba, 4)
|
||||||
SAMPLE_FUNC(SampleBgraLinePair, VP8YuvToBgra, 4)
|
SAMPLE_FUNC(SampleBgraLinePair, VP8YuvToBgra, 4)
|
||||||
|
SAMPLE_FUNC(SampleArgbLinePair, VP8YuvToArgb, 4)
|
||||||
|
SAMPLE_FUNC(SampleArgb4444LinePair, VP8YuvToArgb4444, 2)
|
||||||
|
SAMPLE_FUNC(SampleRgb565LinePair, VP8YuvToRgb565, 2)
|
||||||
|
|
||||||
#undef SAMPLE_FUNC
|
#undef SAMPLE_FUNC
|
||||||
|
|
||||||
@ -175,11 +186,14 @@ typedef void (*SampleLinePairFunc)(
|
|||||||
const uint8_t* u, const uint8_t* v,
|
const uint8_t* u, const uint8_t* v,
|
||||||
uint8_t* top_dst, uint8_t* bottom_dst, int len);
|
uint8_t* top_dst, uint8_t* bottom_dst, int len);
|
||||||
|
|
||||||
static const SampleLinePairFunc kSamplers[MODE_BGRA + 1] = {
|
static const SampleLinePairFunc kSamplers[MODE_LAST] = {
|
||||||
SampleRgbLinePair, // MODE_RGB
|
SampleRgbLinePair, // MODE_RGB
|
||||||
SampleRgbaLinePair, // MODE_RGBA
|
SampleRgbaLinePair, // MODE_RGBA
|
||||||
SampleBgrLinePair, // MODE_BGR
|
SampleBgrLinePair, // MODE_BGR
|
||||||
SampleBgraLinePair // MODE_BGRA
|
SampleBgraLinePair, // MODE_BGRA
|
||||||
|
SampleArgbLinePair, // MODE_ARGB
|
||||||
|
SampleArgb4444LinePair, // MODE_ARGB_4444
|
||||||
|
SampleRgb565LinePair // MODE_RGB_565
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -196,17 +210,23 @@ YUV444_FUNC(Yuv444ToRgb, VP8YuvToRgb, 3)
|
|||||||
YUV444_FUNC(Yuv444ToBgr, VP8YuvToBgr, 3)
|
YUV444_FUNC(Yuv444ToBgr, VP8YuvToBgr, 3)
|
||||||
YUV444_FUNC(Yuv444ToRgba, VP8YuvToRgba, 4)
|
YUV444_FUNC(Yuv444ToRgba, VP8YuvToRgba, 4)
|
||||||
YUV444_FUNC(Yuv444ToBgra, VP8YuvToBgra, 4)
|
YUV444_FUNC(Yuv444ToBgra, VP8YuvToBgra, 4)
|
||||||
|
YUV444_FUNC(Yuv444ToArgb, VP8YuvToArgb, 4)
|
||||||
|
YUV444_FUNC(Yuv444ToArgb4444, VP8YuvToArgb4444, 2)
|
||||||
|
YUV444_FUNC(Yuv444ToRgb565, VP8YuvToRgb565, 2)
|
||||||
|
|
||||||
#undef YUV444_FUNC
|
#undef YUV444_FUNC
|
||||||
|
|
||||||
typedef void (*YUV444Func)(const uint8_t* y, const uint8_t* u, const uint8_t* v,
|
typedef void (*YUV444Func)(const uint8_t* y, const uint8_t* u, const uint8_t* v,
|
||||||
uint8_t* dst, int len);
|
uint8_t* dst, int len);
|
||||||
|
|
||||||
static const YUV444Func kYUV444Converters[MODE_BGRA + 1] = {
|
static const YUV444Func kYUV444Converters[MODE_LAST] = {
|
||||||
Yuv444ToRgb, // MODE_RGB
|
Yuv444ToRgb, // MODE_RGB
|
||||||
Yuv444ToRgba, // MODE_RGBA
|
Yuv444ToRgba, // MODE_RGBA
|
||||||
Yuv444ToBgr, // MODE_BGR
|
Yuv444ToBgr, // MODE_BGR
|
||||||
Yuv444ToBgra // MODE_BGRA
|
Yuv444ToBgra, // MODE_BGRA
|
||||||
|
Yuv444ToArgb, // MODE_ARGB
|
||||||
|
Yuv444ToArgb4444, // MODE_ARGB_4444
|
||||||
|
Yuv444ToRgb565 // MODE_RGB_565
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -517,8 +537,13 @@ static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int IsAlphaMode(WEBP_CSP_MODE mode) {
|
||||||
|
return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB ||
|
||||||
|
mode == MODE_ARGB_4444 || mode == MODE_YUVA);
|
||||||
|
}
|
||||||
|
|
||||||
static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
||||||
const int has_alpha = (p->output->colorspace & MODE_ALPHA_MASK);
|
const int has_alpha = IsAlphaMode(p->output->colorspace);
|
||||||
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
||||||
const int out_width = io->scaled_width;
|
const int out_width = io->scaled_width;
|
||||||
const int out_height = io->scaled_height;
|
const int out_height = io->scaled_height;
|
||||||
@ -653,7 +678,7 @@ static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
||||||
const int has_alpha = (p->output->colorspace & MODE_ALPHA_MASK);
|
const int has_alpha = IsAlphaMode(p->output->colorspace);
|
||||||
const int out_width = io->scaled_width;
|
const int out_width = io->scaled_width;
|
||||||
const int out_height = io->scaled_height;
|
const int out_height = io->scaled_height;
|
||||||
const int uv_in_width = (io->mb_w + 1) >> 1;
|
const int uv_in_width = (io->mb_w + 1) >> 1;
|
||||||
@ -793,7 +818,7 @@ static int CustomSetup(VP8Io* io) {
|
|||||||
p->emit = EmitYUV;
|
p->emit = EmitYUV;
|
||||||
}
|
}
|
||||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||||
if (p->output->colorspace & MODE_ALPHA_MASK) {
|
if (IsAlphaMode(p->output->colorspace)) {
|
||||||
// We need transparency output
|
// We need transparency output
|
||||||
p->emit_alpha = is_rgb ? EmitAlphaRGB : EmitAlphaYUV;
|
p->emit_alpha = is_rgb ? EmitAlphaRGB : EmitAlphaYUV;
|
||||||
}
|
}
|
||||||
|
@ -224,6 +224,11 @@ uint8_t* WebPDecodeRGBA(const uint8_t* data, uint32_t data_size,
|
|||||||
return Decode(MODE_RGBA, data, data_size, width, height, NULL);
|
return Decode(MODE_RGBA, data, data_size, width, height, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t* WebPDecodeARGB(const uint8_t* data, uint32_t data_size,
|
||||||
|
int* width, int* height) {
|
||||||
|
return Decode(MODE_ARGB, data, data_size, width, height, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t* WebPDecodeBGR(const uint8_t* data, uint32_t data_size,
|
uint8_t* WebPDecodeBGR(const uint8_t* data, uint32_t data_size,
|
||||||
int* width, int* height) {
|
int* width, int* height) {
|
||||||
return Decode(MODE_BGR, data, data_size, width, height, NULL);
|
return Decode(MODE_BGR, data, data_size, width, height, NULL);
|
||||||
|
@ -67,8 +67,8 @@ typedef void (*WebPUpsampleLinePairFunc)(
|
|||||||
uint8_t* top_dst, uint8_t* bottom_dst, int len);
|
uint8_t* top_dst, uint8_t* bottom_dst, int len);
|
||||||
|
|
||||||
// Upsampler functions to be used to convert YUV to RGB(A) modes
|
// Upsampler functions to be used to convert YUV to RGB(A) modes
|
||||||
extern WebPUpsampleLinePairFunc WebPUpsamplers[MODE_BGRA + 1];
|
extern WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST];
|
||||||
extern WebPUpsampleLinePairFunc WebPUpsamplersKeepAlpha[MODE_BGRA + 1];
|
extern WebPUpsampleLinePairFunc WebPUpsamplersKeepAlpha[MODE_LAST];
|
||||||
|
|
||||||
// Initializes SSE2 version of the fancy upsamplers.
|
// Initializes SSE2 version of the fancy upsamplers.
|
||||||
void WebPInitUpsamplersSSE2(void);
|
void WebPInitUpsamplersSSE2(void);
|
||||||
|
@ -20,6 +20,7 @@ enum { YUV_HALF = 1 << (YUV_FIX - 1) };
|
|||||||
int16_t VP8kVToR[256], VP8kUToB[256];
|
int16_t VP8kVToR[256], VP8kUToB[256];
|
||||||
int32_t VP8kVToG[256], VP8kUToG[256];
|
int32_t VP8kVToG[256], VP8kUToG[256];
|
||||||
uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
|
uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
|
||||||
|
uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
|
||||||
|
|
||||||
static int done = 0;
|
static int done = 0;
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ void VP8YUVInit(void) {
|
|||||||
for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) {
|
for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) {
|
||||||
const int k = ((i - 16) * 76283 + YUV_HALF) >> YUV_FIX;
|
const int k = ((i - 16) * 76283 + YUV_HALF) >> YUV_FIX;
|
||||||
VP8kClip[i - YUV_RANGE_MIN] = (k < 0) ? 0 : (k > 255) ? 255 : k;
|
VP8kClip[i - YUV_RANGE_MIN] = (k < 0) ? 0 : (k > 255) ? 255 : k;
|
||||||
|
VP8kClip4Bits[i - YUV_RANGE_MIN] = (VP8kClip[i - YUV_RANGE_MIN] + 8) >> 4;
|
||||||
}
|
}
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ enum { YUV_FIX = 16, // fixed-point precision
|
|||||||
extern int16_t VP8kVToR[256], VP8kUToB[256];
|
extern int16_t VP8kVToR[256], VP8kUToB[256];
|
||||||
extern int32_t VP8kVToG[256], VP8kUToG[256];
|
extern int32_t VP8kVToG[256], VP8kUToG[256];
|
||||||
extern uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
|
extern uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
|
||||||
|
extern uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
|
||||||
|
|
||||||
static inline void VP8YuvToRgb(uint8_t y, uint8_t u, uint8_t v,
|
static inline void VP8YuvToRgb(uint8_t y, uint8_t u, uint8_t v,
|
||||||
uint8_t* const rgb) {
|
uint8_t* const rgb) {
|
||||||
@ -36,6 +37,46 @@ static inline void VP8YuvToRgb(uint8_t y, uint8_t u, uint8_t v,
|
|||||||
rgb[2] = VP8kClip[y + b_off - YUV_RANGE_MIN];
|
rgb[2] = VP8kClip[y + b_off - YUV_RANGE_MIN];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void VP8YuvToRgb565(uint8_t y, uint8_t u, uint8_t v,
|
||||||
|
uint8_t* const rgb) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void VP8YuvToArgbKeepA(uint8_t y, uint8_t u, uint8_t v,
|
||||||
|
uint8_t* const argb) {
|
||||||
|
// Don't update Aplha (argb[0])
|
||||||
|
VP8YuvToRgb(y, u, v, argb + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void VP8YuvToArgb(uint8_t y, uint8_t u, uint8_t v,
|
||||||
|
uint8_t* const argb) {
|
||||||
|
argb[0] = 0xff;
|
||||||
|
VP8YuvToArgbKeepA(y, u, v, argb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void VP8YuvToArgb4444KeepA(uint8_t y, uint8_t u, uint8_t v,
|
||||||
|
uint8_t* const argb) {
|
||||||
|
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 Aplha (first 4 bits of argb[0])
|
||||||
|
argb[0] = VP8kClip4Bits[y + r_off - YUV_RANGE_MIN];
|
||||||
|
argb[1] = ((VP8kClip[y + g_off - YUV_RANGE_MIN] & 0xf0) |
|
||||||
|
VP8kClip4Bits[y + b_off - YUV_RANGE_MIN]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void VP8YuvToArgb4444(uint8_t y, uint8_t u, uint8_t v,
|
||||||
|
uint8_t* const argb) {
|
||||||
|
argb[0] = 0xf0;
|
||||||
|
VP8YuvToArgb4444KeepA(y, u, v, argb);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void VP8YuvToBgr(uint8_t y, uint8_t u, uint8_t v,
|
static inline void VP8YuvToBgr(uint8_t y, uint8_t u, uint8_t v,
|
||||||
uint8_t* const bgr) {
|
uint8_t* const bgr) {
|
||||||
const int r_off = VP8kVToR[v];
|
const int r_off = VP8kVToR[v];
|
||||||
|
@ -42,6 +42,10 @@ uint8_t* WebPDecodeRGB(const uint8_t* data, uint32_t data_size,
|
|||||||
uint8_t* WebPDecodeRGBA(const uint8_t* data, uint32_t data_size,
|
uint8_t* WebPDecodeRGBA(const uint8_t* data, uint32_t data_size,
|
||||||
int* width, int* height);
|
int* width, int* height);
|
||||||
|
|
||||||
|
// Same as WebPDecodeRGBA, but returning ARGB data.
|
||||||
|
uint8_t* WebPDecodeARGB(const uint8_t* data, uint32_t data_size,
|
||||||
|
int* width, int* height);
|
||||||
|
|
||||||
// This variant decode to BGR instead of RGB.
|
// This variant decode to BGR instead of RGB.
|
||||||
uint8_t* WebPDecodeBGR(const uint8_t* data, uint32_t data_size,
|
uint8_t* WebPDecodeBGR(const uint8_t* data, uint32_t data_size,
|
||||||
int* width, int* height);
|
int* width, int* height);
|
||||||
@ -102,7 +106,11 @@ uint8_t* WebPDecodeYUVInto(const uint8_t* data, uint32_t data_size,
|
|||||||
// Colorspaces
|
// Colorspaces
|
||||||
typedef enum { MODE_RGB = 0, MODE_RGBA = 1,
|
typedef enum { MODE_RGB = 0, MODE_RGBA = 1,
|
||||||
MODE_BGR = 2, MODE_BGRA = 3,
|
MODE_BGR = 2, MODE_BGRA = 3,
|
||||||
MODE_YUV = 4, MODE_YUVA = 5 // yuv 4:2:0
|
MODE_ARGB = 4, MODE_ARGB_4444 = 5,
|
||||||
|
MODE_RGB_565 = 6,
|
||||||
|
// YUV modes must come after RGB ones.
|
||||||
|
MODE_YUV = 7, MODE_YUVA = 8, // yuv 4:2:0
|
||||||
|
MODE_LAST = 9
|
||||||
} WEBP_CSP_MODE;
|
} WEBP_CSP_MODE;
|
||||||
|
|
||||||
// Generic structure for describing the sample buffer.
|
// Generic structure for describing the sample buffer.
|
||||||
|
Loading…
Reference in New Issue
Block a user