mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-09 14:54:46 +03:00
webp: decode directly to block storage when possible
This commit is contained in:
parent
76c8dda681
commit
bd369f78ae
1
decode.c
1
decode.c
|
@ -763,6 +763,7 @@ PyImaging_WebPDecoderNew(PyObject* self, PyObject* args)
|
||||||
context->has_alpha = has_alpha;
|
context->has_alpha = has_alpha;
|
||||||
context->width = width;
|
context->width = width;
|
||||||
context->height = height;
|
context->height = height;
|
||||||
|
context->output = NULL;
|
||||||
context->decoder = NULL;
|
context->decoder = NULL;
|
||||||
|
|
||||||
return (PyObject*) decoder;
|
return (PyObject*) decoder;
|
||||||
|
|
|
@ -25,6 +25,9 @@ typedef struct {
|
||||||
/* PRIVATE CONTEXT (set by decoder) */
|
/* PRIVATE CONTEXT (set by decoder) */
|
||||||
|
|
||||||
WebPDecoderConfig config;
|
WebPDecoderConfig config;
|
||||||
|
/* Non-NULL when a temporary output buffer is in use. */
|
||||||
|
WebPDecBuffer *output;
|
||||||
|
/* Non-NULL when an incremental decoder is in use. */
|
||||||
WebPIDecoder *decoder;
|
WebPIDecoder *decoder;
|
||||||
|
|
||||||
} WEBPSTATE;
|
} WEBPSTATE;
|
||||||
|
|
|
@ -40,12 +40,11 @@ static int _vp8_status_to_codec_status(VP8StatusCode code)
|
||||||
int ImagingWebPDecode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes)
|
int ImagingWebPDecode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes)
|
||||||
{
|
{
|
||||||
WEBPSTATE *context = (WEBPSTATE *)state->context;
|
WEBPSTATE *context = (WEBPSTATE *)state->context;
|
||||||
|
WebPDecoderConfig *config = &context->config;
|
||||||
VP8StatusCode vp8_status_code;
|
VP8StatusCode vp8_status_code;
|
||||||
|
|
||||||
if (!state->state)
|
if (!state->state)
|
||||||
{
|
{
|
||||||
WebPDecoderConfig *config = &context->config;
|
|
||||||
|
|
||||||
if (!WebPInitDecoderConfig(config))
|
if (!WebPInitDecoderConfig(config))
|
||||||
{
|
{
|
||||||
/* Mismatched version. */
|
/* Mismatched version. */
|
||||||
|
@ -58,6 +57,23 @@ int ImagingWebPDecode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes
|
||||||
else
|
else
|
||||||
config->output.colorspace = MODE_RGB;
|
config->output.colorspace = MODE_RGB;
|
||||||
|
|
||||||
|
/* If block storage is used, and we're not stripping alpha, then directly decode to it. */
|
||||||
|
if (NULL != im->block && (MODE_RGBA == config->output.colorspace || !context->has_alpha))
|
||||||
|
{
|
||||||
|
assert(4 == im->pixelsize);
|
||||||
|
|
||||||
|
/* Force RGBA so RGB is correctly unpacked. */
|
||||||
|
config->output.colorspace = MODE_RGBA;
|
||||||
|
config->output.is_external_memory = 1;
|
||||||
|
config->output.u.RGBA.stride = im->linesize;
|
||||||
|
config->output.u.RGBA.size = config->output.u.RGBA.stride * state->ysize;
|
||||||
|
config->output.u.RGBA.rgba = (uint8_t *)im->block + state->xoff * 4 + state->yoff * im->linesize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context->output = &config->output;
|
||||||
|
}
|
||||||
|
|
||||||
if (state->xsize != context->width || state->ysize != context->height)
|
if (state->xsize != context->width || state->ysize != context->height)
|
||||||
{
|
{
|
||||||
config->options.scaled_width = state->xsize;
|
config->options.scaled_width = state->xsize;
|
||||||
|
@ -102,10 +118,14 @@ int ImagingWebPDecode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes
|
||||||
assert(height == state->ysize);
|
assert(height == state->ysize);
|
||||||
assert(last_y <= state->ysize);
|
assert(last_y <= state->ysize);
|
||||||
|
|
||||||
for (; state->y < last_y; ++state->y)
|
if (config->output.is_external_memory)
|
||||||
|
{
|
||||||
|
state->y = last_y;
|
||||||
|
}
|
||||||
|
else for (; state->y < last_y; ++state->y)
|
||||||
{
|
{
|
||||||
assert(state->y < state->ysize);
|
assert(state->y < state->ysize);
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
state->shuffle((UINT8 *)im->image[state->y + state->yoff] +
|
||||||
state->xoff * im->pixelsize,
|
state->xoff * im->pixelsize,
|
||||||
rgba + state->y * stride, state->xsize);
|
rgba + state->y * stride, state->xsize);
|
||||||
}
|
}
|
||||||
|
@ -131,9 +151,14 @@ int ImagingWebPDecodeCleanup(ImagingCodecState state)
|
||||||
{
|
{
|
||||||
WEBPSTATE* context = (WEBPSTATE*) state->context;
|
WEBPSTATE* context = (WEBPSTATE*) state->context;
|
||||||
|
|
||||||
|
if (NULL != context->output)
|
||||||
|
{
|
||||||
|
WebPFreeDecBuffer(context->output);
|
||||||
|
context->output = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL != context->decoder)
|
if (NULL != context->decoder)
|
||||||
{
|
{
|
||||||
WebPFreeDecBuffer(&context->config.output);
|
|
||||||
WebPIDelete(context->decoder);
|
WebPIDelete(context->decoder);
|
||||||
context->decoder = NULL;
|
context->decoder = NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user