mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-09 06:44:45 +03:00
webp: disable incremental decoding on lossless content
Two reasons: - it's *really* slow on lossless content - it's not incremental on lossless content: decoding will only be done at the end, after the whole data has been pushed to the decoder
This commit is contained in:
parent
2a7fde6c81
commit
ea2ceab377
|
@ -157,6 +157,11 @@ class WebPImageFile(ImageFile.ImageFile):
|
||||||
# Decoder params: rawmode, has_alpha, width, height.
|
# Decoder params: rawmode, has_alpha, width, height.
|
||||||
(mode, 1 if 'RGBA' == mode else 0, size[0], size[1]))]
|
(mode, 1 if 'RGBA' == mode else 0, size[0], size[1]))]
|
||||||
|
|
||||||
|
if not lossy:
|
||||||
|
# Incremental decoding on lossless is *really* slow, disable it.
|
||||||
|
self.decodermaxblock = 12 + i32le(header[4:8])
|
||||||
|
self.decoderconfig = (1,)
|
||||||
|
|
||||||
def draft(self, mode, size):
|
def draft(self, mode, size):
|
||||||
|
|
||||||
if 1 != len(self.tile):
|
if 1 != len(self.tile):
|
||||||
|
|
7
decode.c
7
decode.c
|
@ -740,10 +740,12 @@ PyImaging_WebPDecoderNew(PyObject* self, PyObject* args)
|
||||||
char* rawmode; /* what we wan't from the decoder */
|
char* rawmode; /* what we wan't from the decoder */
|
||||||
int has_alpha;
|
int has_alpha;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
int onepass = 0;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ssiii",
|
if (!PyArg_ParseTuple(args, "ssiii|i",
|
||||||
&mode, &rawmode,
|
&mode, &rawmode,
|
||||||
&has_alpha, &width, &height))
|
&has_alpha, &width, &height,
|
||||||
|
&onepass))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
decoder = PyImaging_DecoderNew(sizeof(WEBPSTATE));
|
decoder = PyImaging_DecoderNew(sizeof(WEBPSTATE));
|
||||||
|
@ -763,6 +765,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->onepass = onepass;
|
||||||
context->output = NULL;
|
context->output = NULL;
|
||||||
context->decoder = NULL;
|
context->decoder = NULL;
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,9 @@ typedef struct {
|
||||||
int has_alpha;
|
int has_alpha;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
|
/* Decoder will receive and decode the data in one pass. */
|
||||||
|
int onepass;
|
||||||
|
|
||||||
/* PRIVATE CONTEXT (set by decoder) */
|
/* PRIVATE CONTEXT (set by decoder) */
|
||||||
|
|
||||||
WebPDecoderConfig config;
|
WebPDecoderConfig config;
|
||||||
|
|
|
@ -81,24 +81,39 @@ int ImagingWebPDecode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes
|
||||||
config->options.use_scaling = 1;
|
config->options.use_scaling = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->decoder = WebPIDecode(NULL, 0, config);
|
if (!context->onepass)
|
||||||
if (NULL == context->decoder)
|
|
||||||
{
|
{
|
||||||
state->errcode = _vp8_status_to_codec_status(vp8_status_code);
|
context->decoder = WebPIDecode(NULL, 0, config);
|
||||||
return -1;
|
if (NULL == context->decoder)
|
||||||
|
{
|
||||||
|
state->errcode = _vp8_status_to_codec_status(vp8_status_code);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state->state = 1;
|
state->state = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Consume the buffer, decoding as much as possible. */
|
if (context->onepass)
|
||||||
vp8_status_code = WebPIAppend(context->decoder, buf, bytes);
|
|
||||||
if (VP8_STATUS_NOT_ENOUGH_DATA != vp8_status_code &&
|
|
||||||
VP8_STATUS_SUSPENDED != vp8_status_code &&
|
|
||||||
VP8_STATUS_OK != vp8_status_code)
|
|
||||||
{
|
{
|
||||||
state->errcode = _vp8_status_to_codec_status(vp8_status_code);
|
vp8_status_code = WebPDecode(buf, bytes, config);
|
||||||
return -1;
|
if (VP8_STATUS_OK != vp8_status_code)
|
||||||
|
{
|
||||||
|
state->errcode = _vp8_status_to_codec_status(vp8_status_code);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Consume the buffer, decoding as much as possible. */
|
||||||
|
vp8_status_code = WebPIAppend(context->decoder, buf, bytes);
|
||||||
|
if (VP8_STATUS_NOT_ENOUGH_DATA != vp8_status_code &&
|
||||||
|
VP8_STATUS_SUSPENDED != vp8_status_code &&
|
||||||
|
VP8_STATUS_OK != vp8_status_code)
|
||||||
|
{
|
||||||
|
state->errcode = _vp8_status_to_codec_status(vp8_status_code);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VP8_STATUS_NOT_ENOUGH_DATA != vp8_status_code)
|
if (VP8_STATUS_NOT_ENOUGH_DATA != vp8_status_code)
|
||||||
|
@ -111,7 +126,19 @@ int ImagingWebPDecode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes
|
||||||
int height;
|
int height;
|
||||||
int stride;
|
int stride;
|
||||||
|
|
||||||
rgba = WebPIDecGetRGB(context->decoder, &last_y, &width, &height, &stride);
|
if (context->onepass)
|
||||||
|
{
|
||||||
|
rgba = config->output.u.RGBA.rgba;
|
||||||
|
last_y = state->ysize;
|
||||||
|
width = state->xsize;
|
||||||
|
height = state->ysize;
|
||||||
|
stride = config->output.u.RGBA.stride;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rgba = WebPIDecGetRGB(context->decoder, &last_y, &width, &height, &stride);
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL != rgba)
|
if (NULL != rgba)
|
||||||
{
|
{
|
||||||
assert(width == state->xsize);
|
assert(width == state->xsize);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user