GIF: Support transparency in the native decoder.

Allow the transparency index to be passed to the native decoder.  If not
-1, pixels with this index will be left at their previous value.

This only adds the decoder support and isn't active yet.
This commit is contained in:
Glenn Maynard 2018-10-23 22:33:57 -05:00 committed by Andrew Murray
parent 8064e04e96
commit a4a314f765
4 changed files with 28 additions and 19 deletions

View File

@ -251,7 +251,7 @@ class GifImageFile(ImageFile.ImageFile):
bits = self.fp.read(1)[0]
self.__offset = self.fp.tell()
self.tile = [
("gif", (x0, y0, x1, y1), self.__offset, (bits, interlace))
("gif", (x0, y0, x1, y1), self.__offset, (bits, interlace, -1))
]
break

View File

@ -430,7 +430,8 @@ PyImaging_GifDecoderNew(PyObject *self, PyObject *args) {
char *mode;
int bits = 8;
int interlace = 0;
if (!PyArg_ParseTuple(args, "s|ii", &mode, &bits, &interlace)) {
int transparency = -1;
if (!PyArg_ParseTuple(args, "s|iii", &mode, &bits, &interlace, &transparency)) {
return NULL;
}
@ -448,6 +449,7 @@ PyImaging_GifDecoderNew(PyObject *self, PyObject *args) {
((GIFDECODERSTATE *)decoder->state.context)->bits = bits;
((GIFDECODERSTATE *)decoder->state.context)->interlace = interlace;
((GIFDECODERSTATE *)decoder->state.context)->transparency = transparency;
return (PyObject *)decoder;
}

View File

@ -30,6 +30,9 @@ typedef struct {
*/
int interlace;
/* The transparent palette index, or -1 for no transparency. */
int transparency;
/* PRIVATE CONTEXT (set by decoder) */
/* Interlace parameters */

View File

@ -248,8 +248,8 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t
/* To squeeze some extra pixels out of this loop, we test for
some common cases and handle them separately. */
/* FIXME: should we handle the transparency index in here??? */
/* If we have transparency, we need to use the regular loop. */
if (context->transparency == -1) {
if (i == 1) {
if (state->x < state->xsize - 1) {
/* Single pixel, not at the end of the line. */
@ -267,10 +267,14 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t
}
continue;
}
}
/* No shortcut, copy pixel by pixel */
for (c = 0; c < i; c++) {
*out++ = p[c];
if (p[c] != context->transparency) {
*out = p[c];
}
out++;
if (++state->x >= state->xsize) {
NEWLINE(state, context);
}