mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
Extract some useful functions around decoding buffer WebPDecParams.
This is to prepare for incremental decoding. Change-Id: Ibb1ac6c1f2d10e096c4fbcf0c06bce77b30ca457
This commit is contained in:
parent
d5bc05a47b
commit
3e856e2dd6
@ -6,7 +6,7 @@ libwebpdecode_la_LDFLAGS = -version-info 0:0:0
|
|||||||
libwebpdecodeinclude_HEADERS = ../webp/decode.h ../webp/decode_vp8.h ../webp/types.h
|
libwebpdecodeinclude_HEADERS = ../webp/decode.h ../webp/decode_vp8.h ../webp/types.h
|
||||||
libwebpdecodeincludedir = $(includedir)/webp
|
libwebpdecodeincludedir = $(includedir)/webp
|
||||||
|
|
||||||
noinst_HEADERS = bits.h vp8i.h yuv.h
|
noinst_HEADERS = bits.h vp8i.h webpi.h yuv.h
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libwebpdecode.la
|
noinst_LTLIBRARIES = libwebpdecode.la
|
||||||
# uncomment the following line (and comment the above) if you want
|
# uncomment the following line (and comment the above) if you want
|
||||||
|
348
src/dec/webp.c
348
src/dec/webp.c
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "vp8i.h"
|
#include "vp8i.h"
|
||||||
|
#include "webpi.h"
|
||||||
#include "yuv.h"
|
#include "yuv.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
@ -37,7 +38,7 @@ static inline uint32_t get_le32(const uint8_t* const data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a RIFF container is detected, validate it and skip over it.
|
// If a RIFF container is detected, validate it and skip over it.
|
||||||
static uint32_t CheckRIFFHeader(const uint8_t** data_ptr,
|
uint32_t WebPCheckRIFFHeader(const uint8_t** data_ptr,
|
||||||
uint32_t *data_size_ptr) {
|
uint32_t *data_size_ptr) {
|
||||||
uint32_t chunk_size = 0xffffffffu;
|
uint32_t chunk_size = 0xffffffffu;
|
||||||
if (*data_size_ptr >= 10 + 20 && !memcmp(*data_ptr, "RIFF", 4)) {
|
if (*data_size_ptr >= 10 + 20 && !memcmp(*data_ptr, "RIFF", 4)) {
|
||||||
@ -68,10 +69,6 @@ static uint32_t CheckRIFFHeader(const uint8_t** data_ptr,
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Fancy upscaling
|
// Fancy upscaling
|
||||||
|
|
||||||
typedef enum { MODE_RGB = 0, MODE_RGBA = 1,
|
|
||||||
MODE_BGR = 2, MODE_BGRA = 3,
|
|
||||||
MODE_YUV = 4 } CSP_MODE;
|
|
||||||
|
|
||||||
#ifdef FANCY_UPSCALING
|
#ifdef FANCY_UPSCALING
|
||||||
|
|
||||||
// Given samples laid out in a square as:
|
// Given samples laid out in a square as:
|
||||||
@ -153,7 +150,7 @@ void UpscaleLinePair(const uint8_t* top_y, const uint8_t* bottom_y,
|
|||||||
const uint8_t* top_u, const uint8_t* top_v,
|
const uint8_t* top_u, const uint8_t* top_v,
|
||||||
const uint8_t* cur_u, const uint8_t* cur_v,
|
const uint8_t* cur_u, const uint8_t* cur_v,
|
||||||
uint8_t* top_dst, uint8_t* bottom_dst, int len,
|
uint8_t* top_dst, uint8_t* bottom_dst, int len,
|
||||||
CSP_MODE mode) {
|
WEBP_CSP_MODE mode) {
|
||||||
if (mode == MODE_RGB) {
|
if (mode == MODE_RGB) {
|
||||||
UpscaleRgbLinePair(top_y, bottom_y, top_u, top_v, cur_u, cur_v,
|
UpscaleRgbLinePair(top_y, bottom_y, top_u, top_v, cur_u, cur_v,
|
||||||
top_dst, bottom_dst, len);
|
top_dst, bottom_dst, len);
|
||||||
@ -178,18 +175,8 @@ void UpscaleLinePair(const uint8_t* top_y, const uint8_t* bottom_y,
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Main conversion driver.
|
// Main conversion driver.
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t* output; // rgb(a) or luma
|
|
||||||
uint8_t *u, *v;
|
|
||||||
uint8_t *top_y, *top_u, *top_v;
|
|
||||||
int stride; // rgb(a) stride or luma stride
|
|
||||||
int u_stride;
|
|
||||||
int v_stride;
|
|
||||||
CSP_MODE mode;
|
|
||||||
} Params;
|
|
||||||
|
|
||||||
static int CustomPut(const VP8Io* io) {
|
static int CustomPut(const VP8Io* io) {
|
||||||
Params *p = (Params*)io->opaque;
|
WebPDecParams *p = (WebPDecParams*)io->opaque;
|
||||||
const int w = io->width;
|
const int w = io->width;
|
||||||
const int mb_h = io->mb_h;
|
const int mb_h = io->mb_h;
|
||||||
const int uv_w = (w + 1) / 2;
|
const int uv_w = (w + 1) / 2;
|
||||||
@ -291,7 +278,7 @@ static int CustomPut(const VP8Io* io) {
|
|||||||
|
|
||||||
static int CustomSetup(VP8Io* io) {
|
static int CustomSetup(VP8Io* io) {
|
||||||
#ifdef FANCY_UPSCALING
|
#ifdef FANCY_UPSCALING
|
||||||
Params *p = (Params*)io->opaque;
|
WebPDecParams *p = (WebPDecParams*)io->opaque;
|
||||||
p->top_y = p->top_u = p->top_v = NULL;
|
p->top_y = p->top_u = p->top_v = NULL;
|
||||||
if (p->mode != MODE_YUV) {
|
if (p->mode != MODE_YUV) {
|
||||||
const int uv_width = (io->width + 1) >> 1;
|
const int uv_width = (io->width + 1) >> 1;
|
||||||
@ -309,7 +296,7 @@ static int CustomSetup(VP8Io* io) {
|
|||||||
|
|
||||||
static void CustomTeardown(const VP8Io* io) {
|
static void CustomTeardown(const VP8Io* io) {
|
||||||
#ifdef FANCY_UPSCALING
|
#ifdef FANCY_UPSCALING
|
||||||
Params *p = (Params*)io->opaque;
|
WebPDecParams *p = (WebPDecParams*)io->opaque;
|
||||||
if (p->top_y) {
|
if (p->top_y) {
|
||||||
free(p->top_y);
|
free(p->top_y);
|
||||||
p->top_y = p->top_u = p->top_v = NULL;
|
p->top_y = p->top_u = p->top_v = NULL;
|
||||||
@ -317,154 +304,26 @@ static void CustomTeardown(const VP8Io* io) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
void WebPInitCustomIo(VP8Io* const io) {
|
||||||
// "Into" variants
|
io->put = CustomPut;
|
||||||
|
io->setup = CustomSetup;
|
||||||
static uint8_t* DecodeInto(CSP_MODE mode,
|
io->teardown = CustomTeardown;
|
||||||
const uint8_t* data, uint32_t data_size,
|
|
||||||
Params* params, int output_size,
|
|
||||||
int output_u_size, int output_v_size) {
|
|
||||||
VP8Decoder* dec = VP8New();
|
|
||||||
VP8Io io;
|
|
||||||
int ok = 1;
|
|
||||||
|
|
||||||
if (dec == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8InitIo(&io);
|
|
||||||
io.data = data;
|
|
||||||
io.data_size = data_size;
|
|
||||||
|
|
||||||
params->mode = mode;
|
|
||||||
io.opaque = params;
|
|
||||||
io.put = CustomPut;
|
|
||||||
io.setup = CustomSetup;
|
|
||||||
io.teardown = CustomTeardown;
|
|
||||||
|
|
||||||
if (!VP8GetHeaders(dec, &io)) {
|
|
||||||
VP8Delete(dec);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// check output buffers
|
|
||||||
|
|
||||||
ok &= (params->stride * io.height <= output_size);
|
|
||||||
if (mode == MODE_RGB || mode == MODE_BGR) {
|
|
||||||
ok &= (params->stride >= io.width * 3);
|
|
||||||
} else if (mode == MODE_RGBA || mode == MODE_BGRA) {
|
|
||||||
ok &= (params->stride >= io.width * 4);
|
|
||||||
} else {
|
|
||||||
// some extra checks for U/V
|
|
||||||
const int u_size = params->u_stride * ((io.height + 1) / 2);
|
|
||||||
const int v_size = params->v_stride * ((io.height + 1) / 2);
|
|
||||||
ok &= (params->stride >= io.width);
|
|
||||||
ok &= (params->u_stride >= (io.width + 1) / 2) &&
|
|
||||||
(params->v_stride >= (io.width + 1) / 2);
|
|
||||||
ok &= (u_size <= output_u_size && v_size <= output_v_size);
|
|
||||||
}
|
|
||||||
if (!ok) {
|
|
||||||
VP8Delete(dec);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode != MODE_YUV) {
|
|
||||||
VP8YUVInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = VP8Decode(dec, &io);
|
|
||||||
VP8Delete(dec);
|
|
||||||
return ok ? params->output : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* WebPDecodeRGBInto(const uint8_t* data, uint32_t data_size,
|
|
||||||
uint8_t* output, int output_size,
|
|
||||||
int output_stride) {
|
|
||||||
Params params;
|
|
||||||
|
|
||||||
if (output == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
params.output = output;
|
|
||||||
params.stride = output_stride;
|
|
||||||
return DecodeInto(MODE_RGB, data, data_size, ¶ms, output_size, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* WebPDecodeRGBAInto(const uint8_t* data, uint32_t data_size,
|
|
||||||
uint8_t* output, int output_size,
|
|
||||||
int output_stride) {
|
|
||||||
Params params;
|
|
||||||
|
|
||||||
if (output == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
params.output = output;
|
|
||||||
params.stride = output_stride;
|
|
||||||
return DecodeInto(MODE_RGBA, data, data_size, ¶ms, output_size, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* WebPDecodeBGRInto(const uint8_t* data, uint32_t data_size,
|
|
||||||
uint8_t* output, int output_size,
|
|
||||||
int output_stride) {
|
|
||||||
Params params;
|
|
||||||
|
|
||||||
if (output == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
params.output = output;
|
|
||||||
params.stride = output_stride;
|
|
||||||
return DecodeInto(MODE_BGR, data, data_size, ¶ms, output_size, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* WebPDecodeBGRAInto(const uint8_t* data, uint32_t data_size,
|
|
||||||
uint8_t* output, int output_size,
|
|
||||||
int output_stride) {
|
|
||||||
Params params;
|
|
||||||
|
|
||||||
if (output == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
params.output = output;
|
|
||||||
params.stride = output_stride;
|
|
||||||
return DecodeInto(MODE_BGRA, data, data_size, ¶ms, output_size, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* WebPDecodeYUVInto(const uint8_t* data, uint32_t data_size,
|
|
||||||
uint8_t* luma, int luma_size, int luma_stride,
|
|
||||||
uint8_t* u, int u_size, int u_stride,
|
|
||||||
uint8_t* v, int v_size, int v_stride) {
|
|
||||||
Params params;
|
|
||||||
|
|
||||||
if (luma == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
params.output = luma;
|
|
||||||
params.stride = luma_stride;
|
|
||||||
params.u = u;
|
|
||||||
params.u_stride = u_stride;
|
|
||||||
params.v = v;
|
|
||||||
params.v_stride = v_stride;
|
|
||||||
return DecodeInto(MODE_YUV, data, data_size, ¶ms,
|
|
||||||
luma_size, u_size, v_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
// Init/Check decoding parameters
|
||||||
|
|
||||||
static uint8_t* Decode(CSP_MODE mode, const uint8_t* data, uint32_t data_size,
|
int WebPInitDecParams(const uint8_t* data, uint32_t data_size, int* width,
|
||||||
int* width, int* height, Params* params_out) {
|
int* height, WebPDecParams* const params) {
|
||||||
int w, h, stride;
|
int w, h, stride;
|
||||||
int uv_size = 0;
|
int uv_size = 0;
|
||||||
int uv_stride = 0;
|
int uv_stride = 0;
|
||||||
int size;
|
int size;
|
||||||
uint8_t* output;
|
uint8_t* output;
|
||||||
Params params = { 0 };
|
WEBP_CSP_MODE mode = params->mode;
|
||||||
|
|
||||||
if (!WebPGetInfo(data, data_size, &w, &h)) {
|
if (!WebPGetInfo(data, data_size, &w, &h)) {
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
if (width) *width = w;
|
if (width) *width = w;
|
||||||
if (height) *height = h;
|
if (height) *height = h;
|
||||||
@ -482,18 +341,179 @@ static uint8_t* Decode(CSP_MODE mode, const uint8_t* data, uint32_t data_size,
|
|||||||
|
|
||||||
output = (uint8_t*)malloc(size + 2 * uv_size);
|
output = (uint8_t*)malloc(size + 2 * uv_size);
|
||||||
if (!output) {
|
if (!output) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
params->output = output;
|
||||||
|
params->stride = stride;
|
||||||
|
if (mode == MODE_YUV) {
|
||||||
|
params->u = output + size;
|
||||||
|
params->u_stride = uv_stride;
|
||||||
|
params->v = output + size + uv_size;
|
||||||
|
params->v_stride = uv_stride;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebPCheckDecParams(const VP8Io* io, const WebPDecParams* params,
|
||||||
|
int output_size, int output_u_size, int output_v_size) {
|
||||||
|
int ok = 1;
|
||||||
|
WEBP_CSP_MODE mode = params->mode;
|
||||||
|
ok &= (params->stride * io->height <= output_size);
|
||||||
|
if (mode == MODE_RGB || mode == MODE_BGR) {
|
||||||
|
ok &= (params->stride >= io->width * 3);
|
||||||
|
} else if (mode == MODE_RGBA || mode == MODE_BGRA) {
|
||||||
|
ok &= (params->stride >= io->width * 4);
|
||||||
|
} else {
|
||||||
|
// some extra checks for U/V
|
||||||
|
const int u_size = params->u_stride * ((io->height + 1) / 2);
|
||||||
|
const int v_size = params->v_stride * ((io->height + 1) / 2);
|
||||||
|
ok &= (params->stride >= io->width);
|
||||||
|
ok &= (params->u_stride >= (io->width + 1) / 2) &&
|
||||||
|
(params->v_stride >= (io->width + 1) / 2);
|
||||||
|
ok &= (u_size <= output_u_size && v_size <= output_v_size);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// "Into" variants
|
||||||
|
|
||||||
|
static uint8_t* DecodeInto(WEBP_CSP_MODE mode,
|
||||||
|
const uint8_t* data, uint32_t data_size,
|
||||||
|
WebPDecParams* params, int output_size,
|
||||||
|
int output_u_size, int output_v_size) {
|
||||||
|
VP8Decoder* dec = VP8New();
|
||||||
|
VP8Io io;
|
||||||
|
int ok = 1;
|
||||||
|
|
||||||
|
if (dec == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VP8InitIo(&io);
|
||||||
|
io.data = data;
|
||||||
|
io.data_size = data_size;
|
||||||
|
|
||||||
|
params->mode = mode;
|
||||||
|
io.opaque = params;
|
||||||
|
WebPInitCustomIo(&io);
|
||||||
|
|
||||||
|
if (!VP8GetHeaders(dec, &io)) {
|
||||||
|
VP8Delete(dec);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check output buffers
|
||||||
|
ok = WebPCheckDecParams(&io, params, output_size,
|
||||||
|
output_u_size, output_v_size);
|
||||||
|
if (!ok) {
|
||||||
|
VP8Delete(dec);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode != MODE_YUV) {
|
||||||
|
VP8YUVInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = VP8Decode(dec, &io);
|
||||||
|
VP8Delete(dec);
|
||||||
|
return ok ? params->output : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* WebPDecodeRGBInto(const uint8_t* data, uint32_t data_size,
|
||||||
|
uint8_t* output, int output_size,
|
||||||
|
int output_stride) {
|
||||||
|
WebPDecParams params;
|
||||||
|
|
||||||
|
if (output == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
params.output = output;
|
params.output = output;
|
||||||
params.stride = stride;
|
params.stride = output_stride;
|
||||||
if (mode == MODE_YUV) {
|
return DecodeInto(MODE_RGB, data, data_size, ¶ms, output_size, 0, 0);
|
||||||
params.u = output + size;
|
}
|
||||||
params.u_stride = uv_stride;
|
|
||||||
params.v = output + size + uv_size;
|
uint8_t* WebPDecodeRGBAInto(const uint8_t* data, uint32_t data_size,
|
||||||
params.v_stride = uv_stride;
|
uint8_t* output, int output_size,
|
||||||
|
int output_stride) {
|
||||||
|
WebPDecParams params;
|
||||||
|
|
||||||
|
if (output == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
params.output = output;
|
||||||
|
params.stride = output_stride;
|
||||||
|
return DecodeInto(MODE_RGBA, data, data_size, ¶ms, output_size, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* WebPDecodeBGRInto(const uint8_t* data, uint32_t data_size,
|
||||||
|
uint8_t* output, int output_size,
|
||||||
|
int output_stride) {
|
||||||
|
WebPDecParams params;
|
||||||
|
|
||||||
|
if (output == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
params.output = output;
|
||||||
|
params.stride = output_stride;
|
||||||
|
return DecodeInto(MODE_BGR, data, data_size, ¶ms, output_size, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* WebPDecodeBGRAInto(const uint8_t* data, uint32_t data_size,
|
||||||
|
uint8_t* output, int output_size,
|
||||||
|
int output_stride) {
|
||||||
|
WebPDecParams params;
|
||||||
|
|
||||||
|
if (output == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
params.output = output;
|
||||||
|
params.stride = output_stride;
|
||||||
|
return DecodeInto(MODE_BGRA, data, data_size, ¶ms, output_size, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* WebPDecodeYUVInto(const uint8_t* data, uint32_t data_size,
|
||||||
|
uint8_t* luma, int luma_size, int luma_stride,
|
||||||
|
uint8_t* u, int u_size, int u_stride,
|
||||||
|
uint8_t* v, int v_size, int v_stride) {
|
||||||
|
WebPDecParams params;
|
||||||
|
|
||||||
|
if (luma == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
params.output = luma;
|
||||||
|
params.stride = luma_stride;
|
||||||
|
params.u = u;
|
||||||
|
params.u_stride = u_stride;
|
||||||
|
params.v = v;
|
||||||
|
params.v_stride = v_stride;
|
||||||
|
return DecodeInto(MODE_YUV, data, data_size, ¶ms,
|
||||||
|
luma_size, u_size, v_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static uint8_t* Decode(WEBP_CSP_MODE mode, const uint8_t* data,
|
||||||
|
uint32_t data_size, int* width, int* height,
|
||||||
|
WebPDecParams* params_out) {
|
||||||
|
int size = 0;
|
||||||
|
int uv_size = 0;
|
||||||
|
WebPDecParams params = { 0 };
|
||||||
|
|
||||||
|
params.mode = mode;
|
||||||
|
if (!WebPInitDecParams(data, data_size, width, height, ¶ms)) {
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
if (params_out) *params_out = params;
|
if (params_out) *params_out = params;
|
||||||
|
|
||||||
|
size = params.stride * (*height);
|
||||||
|
uv_size = params.u_stride * ((*height + 1) / 2);
|
||||||
return DecodeInto(mode, data, data_size, ¶ms, size, uv_size, uv_size);
|
return DecodeInto(mode, data, data_size, ¶ms, size, uv_size, uv_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,7 +540,7 @@ uint8_t* WebPDecodeBGRA(const uint8_t* data, uint32_t data_size,
|
|||||||
uint8_t* WebPDecodeYUV(const uint8_t* data, uint32_t data_size,
|
uint8_t* WebPDecodeYUV(const uint8_t* data, uint32_t data_size,
|
||||||
int *width, int *height, uint8_t** u, uint8_t** v,
|
int *width, int *height, uint8_t** u, uint8_t** v,
|
||||||
int *stride, int* uv_stride) {
|
int *stride, int* uv_stride) {
|
||||||
Params params;
|
WebPDecParams params;
|
||||||
uint8_t* const out = Decode(MODE_YUV, data, data_size,
|
uint8_t* const out = Decode(MODE_YUV, data, data_size,
|
||||||
width, height, ¶ms);
|
width, height, ¶ms);
|
||||||
|
|
||||||
@ -539,7 +559,7 @@ uint8_t* WebPDecodeYUV(const uint8_t* data, uint32_t data_size,
|
|||||||
|
|
||||||
int WebPGetInfo(const uint8_t* data, uint32_t data_size,
|
int WebPGetInfo(const uint8_t* data, uint32_t data_size,
|
||||||
int *width, int *height) {
|
int *width, int *height) {
|
||||||
const uint32_t chunk_size = CheckRIFFHeader(&data, &data_size);
|
const uint32_t chunk_size = WebPCheckRIFFHeader(&data, &data_size);
|
||||||
if (!chunk_size) {
|
if (!chunk_size) {
|
||||||
return 0; // unsupported RIFF header
|
return 0; // unsupported RIFF header
|
||||||
}
|
}
|
||||||
|
59
src/dec/webpi.h
Normal file
59
src/dec/webpi.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright 2011 Google Inc.
|
||||||
|
//
|
||||||
|
// This code is licensed under the same terms as WebM:
|
||||||
|
// Software License Agreement: http://www.webmproject.org/license/software/
|
||||||
|
// Additional IP Rights Grant: http://www.webmproject.org/license/additional/
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Internal header: WebP decoding parameters and custom IO on buffer
|
||||||
|
//
|
||||||
|
// Author: somnath@google.com (Somnath Banerjee)
|
||||||
|
|
||||||
|
#ifndef WEBP_DEC_WEBPI_H
|
||||||
|
#define WEBP_DEC_WEBPI_H
|
||||||
|
|
||||||
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "webp/decode_vp8.h"
|
||||||
|
|
||||||
|
typedef enum { MODE_RGB = 0, MODE_RGBA = 1,
|
||||||
|
MODE_BGR = 2, MODE_BGRA = 3,
|
||||||
|
MODE_YUV = 4 } WEBP_CSP_MODE;
|
||||||
|
|
||||||
|
// Decoding output parameters.
|
||||||
|
typedef struct {
|
||||||
|
uint8_t* output; // rgb(a) or luma
|
||||||
|
uint8_t *u, *v;
|
||||||
|
uint8_t *top_y, *top_u, *top_v;
|
||||||
|
int stride; // rgb(a) stride or luma stride
|
||||||
|
int u_stride;
|
||||||
|
int v_stride;
|
||||||
|
WEBP_CSP_MODE mode;
|
||||||
|
} WebPDecParams;
|
||||||
|
|
||||||
|
// If a RIFF container is detected, validate it and skip over it. Returns
|
||||||
|
// VP8 bit-stream size if RIFF header is valid else returns 0
|
||||||
|
uint32_t WebPCheckRIFFHeader(const uint8_t** data_ptr,
|
||||||
|
uint32_t *data_size_ptr);
|
||||||
|
|
||||||
|
// Initializes VP8Io with custom setup, io and teardown functions
|
||||||
|
void WebPInitCustomIo(VP8Io* const io);
|
||||||
|
|
||||||
|
// Initializes params_out by allocating output buffer and setting the
|
||||||
|
// stride information. It also outputs width and height information of
|
||||||
|
// the WebP image. Returns 1 if succeeds.
|
||||||
|
int WebPInitDecParams(const uint8_t* data, uint32_t data_size, int* width,
|
||||||
|
int* height, WebPDecParams* const params_out);
|
||||||
|
|
||||||
|
// Verifies various size configurations (e.g stride >= width, specified
|
||||||
|
// output size <= stride * height etc.). Returns 0 if checks fail.
|
||||||
|
int WebPCheckDecParams(const VP8Io* io, const WebPDecParams* params,
|
||||||
|
int output_size, int output_u_size, int output_v_size);
|
||||||
|
|
||||||
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // WEBP_DEC_WEBPI_H
|
Loading…
Reference in New Issue
Block a user