diff options
author | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 14:39:34 +0300 |
---|---|---|
committer | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 16:42:24 +0300 |
commit | 77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch) | |
tree | c51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/Pillow/py2/libImaging/GifDecode.c | |
parent | dd6d20cadb65582270ac23f4b3b14ae189704b9d (diff) | |
download | ydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz |
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/Pillow/py2/libImaging/GifDecode.c')
-rw-r--r-- | contrib/python/Pillow/py2/libImaging/GifDecode.c | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/contrib/python/Pillow/py2/libImaging/GifDecode.c b/contrib/python/Pillow/py2/libImaging/GifDecode.c new file mode 100644 index 0000000000..68429ab26c --- /dev/null +++ b/contrib/python/Pillow/py2/libImaging/GifDecode.c @@ -0,0 +1,297 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * a fast, suspendable GIF decoder + * + * history: + * 95-09-03 fl Created + * 95-09-05 fl Fixed sign problem on 16-bit platforms + * 95-09-13 fl Added some storage shortcuts + * 96-03-28 fl Revised API, integrated with PIL + * 96-12-10 fl Added interlace support + * 96-12-16 fl Fixed premature termination bug introduced by last fix + * 97-01-05 fl Don't mess up on bogus configuration + * 97-01-17 fl Don't mess up on very small, interlaced files + * 99-02-07 fl Minor speedups + * + * Copyright (c) Secret Labs AB 1997-99. + * Copyright (c) Fredrik Lundh 1995-97. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#include <stdio.h> +#include <memory.h> /* memcpy() */ + +#include "Gif.h" + + +#define NEWLINE(state, context) {\ + state->x = 0;\ + state->y += context->step;\ + while (state->y >= state->ysize)\ + switch (context->interlace) {\ + case 1:\ + context->repeat = state->y = 4;\ + context->interlace = 2;\ + break;\ + case 2:\ + context->step = 4;\ + context->repeat = state->y = 2;\ + context->interlace = 3;\ + break;\ + case 3:\ + context->step = 2;\ + context->repeat = state->y = 1;\ + context->interlace = 0;\ + break;\ + default:\ + return -1;\ + }\ + if (state->y < state->ysize)\ + out = im->image8[state->y + state->yoff] + state->xoff;\ +} + + +int +ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t bytes) +{ + UINT8* p; + UINT8* out; + int c, i; + int thiscode; + GIFDECODERSTATE *context = (GIFDECODERSTATE*) state->context; + + UINT8 *ptr = buffer; + + if (!state->state) { + + /* Initialise state */ + if (context->bits < 0 || context->bits > 12) { + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + } + + /* Clear code */ + context->clear = 1 << context->bits; + + /* End code */ + context->end = context->clear + 1; + + /* Interlace */ + if (context->interlace) { + context->interlace = 1; + context->step = context->repeat = 8; + } else + context->step = 1; + + state->state = 1; + } + + out = im->image8[state->y + state->yoff] + state->xoff + state->x; + + for (;;) { + + if (state->state == 1) { + + /* First free entry in table */ + context->next = context->clear + 2; + + /* Initial code size */ + context->codesize = context->bits + 1; + context->codemask = (1 << context->codesize) - 1; + + /* Buffer pointer. We fill the buffer from right, which + allows us to return all of it in one operation. */ + context->bufferindex = GIFBUFFER; + + state->state = 2; + } + + if (context->bufferindex < GIFBUFFER) { + + /* Return whole buffer in one chunk */ + i = GIFBUFFER - context->bufferindex; + p = &context->buffer[context->bufferindex]; + + context->bufferindex = GIFBUFFER; + + } else { + + /* Get current symbol */ + + while (context->bitcount < context->codesize) { + + if (context->blocksize > 0) { + + /* Read next byte */ + c = *ptr++; bytes--; + + context->blocksize--; + + /* New bits are shifted in from from the left. */ + context->bitbuffer |= (INT32) c << context->bitcount; + context->bitcount += 8; + + } else { + + /* New GIF block */ + + /* We don't start decoding unless we have a full block */ + if (bytes < 1) + return ptr - buffer; + c = *ptr; + if (bytes < c+1) + return ptr - buffer; + + context->blocksize = c; + + ptr++; bytes--; + + } + } + + /* Extract current symbol from bit buffer. */ + c = (int) context->bitbuffer & context->codemask; + + /* Adjust buffer */ + context->bitbuffer >>= context->codesize; + context->bitcount -= context->codesize; + + /* If c is less than "clear", it's a data byte. Otherwise, + it's either clear/end or a code symbol which should be + expanded. */ + + if (c == context->clear) { + if (state->state != 2) + state->state = 1; + continue; + } + + if (c == context->end) + break; + + i = 1; + p = &context->lastdata; + + if (state->state == 2) { + + /* First valid symbol after clear; use as is */ + if (c > context->clear) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + context->lastdata = context->lastcode = c; + state->state = 3; + + } else { + + thiscode = c; + + if (c > context->next) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + if (c == context->next) { + + /* c == next is allowed. not sure why. */ + + if (context->bufferindex <= 0) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + context->buffer[--context->bufferindex] = + context->lastdata; + + c = context->lastcode; + + } + + while (c >= context->clear) { + + /* Copy data string to buffer (beginning from right) */ + + if (context->bufferindex <= 0 || c >= GIFTABLE) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + context->buffer[--context->bufferindex] = + context->data[c]; + + c = context->link[c]; + } + + context->lastdata = c; + + if (context->next < GIFTABLE) { + + /* We'll only add this symbol if we have room + for it (take advise, Netscape!) */ + context->data[context->next] = c; + context->link[context->next] = context->lastcode; + + if (context->next == context->codemask && + context->codesize < GIFBITS) { + + /* Expand code size */ + context->codesize++; + context->codemask = (1 << context->codesize) - 1; + } + + context->next++; + + } + + context->lastcode = thiscode; + + } + } + + /* Copy the bytes into the image */ + if (state->y >= state->ysize) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + + /* 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 (i == 1) { + if (state->x < state->xsize-1) { + /* Single pixel, not at the end of the line. */ + *out++ = p[0]; + state->x++; + continue; + } + } else if (state->x + i <= state->xsize) { + /* This string fits into current line. */ + memcpy(out, p, i); + out += i; + state->x += i; + if (state->x == state->xsize) { + NEWLINE(state, context); + } + continue; + } + + /* No shortcut, copy pixel by pixel */ + for (c = 0; c < i; c++) { + *out++ = p[c]; + if (++state->x >= state->xsize) { + NEWLINE(state, context); + } + } + } + + return ptr - buffer; +} |