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.
|
||||
(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):
|
||||
|
||||
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 */
|
||||
int has_alpha;
|
||||
int width, height;
|
||||
int onepass = 0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ssiii",
|
||||
if (!PyArg_ParseTuple(args, "ssiii|i",
|
||||
&mode, &rawmode,
|
||||
&has_alpha, &width, &height))
|
||||
&has_alpha, &width, &height,
|
||||
&onepass))
|
||||
return NULL;
|
||||
|
||||
decoder = PyImaging_DecoderNew(sizeof(WEBPSTATE));
|
||||
|
@ -763,6 +765,7 @@ PyImaging_WebPDecoderNew(PyObject* self, PyObject* args)
|
|||
context->has_alpha = has_alpha;
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->onepass = onepass;
|
||||
context->output = NULL;
|
||||
context->decoder = NULL;
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@ typedef struct {
|
|||
int has_alpha;
|
||||
int width, height;
|
||||
|
||||
/* Decoder will receive and decode the data in one pass. */
|
||||
int onepass;
|
||||
|
||||
/* PRIVATE CONTEXT (set by decoder) */
|
||||
|
||||
WebPDecoderConfig config;
|
||||
|
|
|
@ -81,24 +81,39 @@ int ImagingWebPDecode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes
|
|||
config->options.use_scaling = 1;
|
||||
}
|
||||
|
||||
context->decoder = WebPIDecode(NULL, 0, config);
|
||||
if (NULL == context->decoder)
|
||||
if (!context->onepass)
|
||||
{
|
||||
state->errcode = _vp8_status_to_codec_status(vp8_status_code);
|
||||
return -1;
|
||||
context->decoder = WebPIDecode(NULL, 0, config);
|
||||
if (NULL == context->decoder)
|
||||
{
|
||||
state->errcode = _vp8_status_to_codec_status(vp8_status_code);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
state->state = 1;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
if (context->onepass)
|
||||
{
|
||||
state->errcode = _vp8_status_to_codec_status(vp8_status_code);
|
||||
return -1;
|
||||
vp8_status_code = WebPDecode(buf, bytes, config);
|
||||
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)
|
||||
|
@ -111,7 +126,19 @@ int ImagingWebPDecode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes
|
|||
int height;
|
||||
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)
|
||||
{
|
||||
assert(width == state->xsize);
|
||||
|
|
Loading…
Reference in New Issue
Block a user