Pillow/src/libImaging/BitDecode.c

139 lines
4.0 KiB
C
Raw Normal View History

2010-07-31 06:52:47 +04:00
/*
* The Python Imaging Library.
* $Id$
*
* decoder for packed bitfields (converts to floating point)
*
* history:
2020-05-01 15:08:57 +03:00
* 97-05-31 fl created (much more than originally intended)
2010-07-31 06:52:47 +04:00
*
* Copyright (c) Fredrik Lundh 1997.
* Copyright (c) Secret Labs AB 1997.
*
* See the README file for information on usage and redistribution.
*/
#include "Imaging.h"
#include "Bit.h"
int
2021-01-03 06:17:51 +03:00
ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
BITSTATE *bitstate = state->context;
UINT8 *ptr;
2010-07-31 06:52:47 +04:00
if (state->state == 0) {
2020-05-01 15:08:57 +03:00
/* Initialize context variables */
2010-07-31 06:52:47 +04:00
/* this decoder only works for float32 image buffers */
if (im->type != IMAGING_TYPE_FLOAT32) {
2020-05-01 15:08:57 +03:00
state->errcode = IMAGING_CODEC_CONFIG;
return -1;
2010-07-31 06:52:47 +04:00
}
/* sanity check */
if (bitstate->bits < 1 || bitstate->bits >= 32) {
2020-05-01 15:08:57 +03:00
state->errcode = IMAGING_CODEC_CONFIG;
return -1;
2010-07-31 06:52:47 +04:00
}
2021-01-03 06:17:51 +03:00
bitstate->mask = (1 << bitstate->bits) - 1;
2010-07-31 06:52:47 +04:00
2020-05-10 12:56:36 +03:00
if (bitstate->sign) {
2021-01-03 06:17:51 +03:00
bitstate->signmask = (1 << (bitstate->bits - 1));
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
2020-05-01 15:08:57 +03:00
/* check image orientation */
if (state->ystep < 0) {
2021-01-03 06:17:51 +03:00
state->y = state->ysize - 1;
2020-05-01 15:08:57 +03:00
state->ystep = -1;
2020-05-10 12:56:36 +03:00
} else {
2020-05-01 15:08:57 +03:00
state->ystep = 1;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
2020-05-01 15:08:57 +03:00
state->state = 1;
2010-07-31 06:52:47 +04:00
}
ptr = buf;
while (bytes > 0) {
UINT8 byte = *ptr;
ptr++;
bytes--;
/* get a byte from the input stream and insert in the bit buffer */
2021-01-03 06:17:51 +03:00
if (bitstate->fill & 1) {
2010-07-31 06:52:47 +04:00
/* fill MSB first */
2021-01-03 06:17:51 +03:00
bitstate->bitbuffer |= (unsigned long)byte << bitstate->bitcount;
2020-05-10 12:56:36 +03:00
} else {
2010-07-31 06:52:47 +04:00
/* fill LSB first */
bitstate->bitbuffer = (bitstate->bitbuffer << 8) | byte;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
bitstate->bitcount += 8;
2010-07-31 06:52:47 +04:00
while (bitstate->bitcount >= bitstate->bits) {
/* get a pixel from the bit buffer */
unsigned long data;
FLOAT32 pixel;
2021-01-03 06:17:51 +03:00
if (bitstate->fill & 2) {
2010-07-31 06:52:47 +04:00
/* store LSB first */
data = bitstate->bitbuffer & bitstate->mask;
2020-05-10 12:56:36 +03:00
if (bitstate->bitcount > 32) {
2010-07-31 06:52:47 +04:00
/* bitbuffer overflow; restore it from last input byte */
2021-01-03 06:17:51 +03:00
bitstate->bitbuffer =
byte >> (8 - (bitstate->bitcount - bitstate->bits));
2020-05-10 12:56:36 +03:00
} else {
2010-07-31 06:52:47 +04:00
bitstate->bitbuffer >>= bitstate->bits;
2020-05-10 12:56:36 +03:00
}
} else {
2010-07-31 06:52:47 +04:00
/* store MSB first */
2021-01-03 06:17:51 +03:00
data = (bitstate->bitbuffer >> (bitstate->bitcount - bitstate->bits)) &
bitstate->mask;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
bitstate->bitcount -= bitstate->bits;
if (bitstate->lutsize > 0) {
/* map through lookup table */
2020-05-10 12:56:36 +03:00
if (data <= 0) {
2010-07-31 06:52:47 +04:00
pixel = bitstate->lut[0];
2020-05-10 12:56:36 +03:00
} else if (data >= bitstate->lutsize) {
2021-01-03 06:17:51 +03:00
pixel = bitstate->lut[bitstate->lutsize - 1];
2020-05-10 12:56:36 +03:00
} else {
2010-07-31 06:52:47 +04:00
pixel = bitstate->lut[data];
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
} else {
/* convert */
2020-05-10 12:56:36 +03:00
if (data & bitstate->signmask) {
2010-07-31 06:52:47 +04:00
/* image memory contains signed data */
2021-01-03 06:17:51 +03:00
pixel = (FLOAT32)(INT32)(data | ~bitstate->mask);
2020-05-10 12:56:36 +03:00
} else {
2021-01-03 06:17:51 +03:00
pixel = (FLOAT32)data;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
2021-01-03 06:17:51 +03:00
*(FLOAT32 *)(&im->image32[state->y][state->x]) = pixel;
2010-07-31 06:52:47 +04:00
/* step forward */
2020-05-01 15:08:57 +03:00
if (++state->x >= state->xsize) {
2010-07-31 06:52:47 +04:00
/* new line */
state->y += state->ystep;
if (state->y < 0 || state->y >= state->ysize) {
/* end of file (errcode = 0) */
return -1;
}
state->x = 0;
/* reset bit buffer */
2020-05-10 12:56:36 +03:00
if (bitstate->pad > 0) {
2010-07-31 06:52:47 +04:00
bitstate->bitcount = 0;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
}
}
return ptr - buf;
}