Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Imaging/libImaging/BitDecode.c
diff options
context:
space:
mode:
Diffstat (limited to 'Imaging/libImaging/BitDecode.c')
-rw-r--r--Imaging/libImaging/BitDecode.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/Imaging/libImaging/BitDecode.c b/Imaging/libImaging/BitDecode.c
new file mode 100644
index 0000000..fef719e
--- /dev/null
+++ b/Imaging/libImaging/BitDecode.c
@@ -0,0 +1,138 @@
+/*
+ * The Python Imaging Library.
+ * $Id: BitDecode.c 2278 2005-02-07 20:27:33Z fredrik $
+ *
+ * decoder for packed bitfields (converts to floating point)
+ *
+ * history:
+ * 97-05-31 fl created (much more than originally intended)
+ *
+ * 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
+ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
+{
+ BITSTATE* bitstate = state->context;
+ UINT8* ptr;
+
+ if (state->state == 0) {
+
+ /* Initialize context variables */
+
+ /* this decoder only works for float32 image buffers */
+ if (im->type != IMAGING_TYPE_FLOAT32) {
+ state->errcode = IMAGING_CODEC_CONFIG;
+ return -1;
+ }
+
+ /* sanity check */
+ if (bitstate->bits < 1 || bitstate->bits >= 32) {
+ state->errcode = IMAGING_CODEC_CONFIG;
+ return -1;
+ }
+
+ bitstate->mask = (1<<bitstate->bits)-1;
+
+ if (bitstate->sign)
+ bitstate->signmask = (1<<(bitstate->bits-1));
+
+ /* check image orientation */
+ if (state->ystep < 0) {
+ state->y = state->ysize-1;
+ state->ystep = -1;
+ } else
+ state->ystep = 1;
+
+ state->state = 1;
+
+ }
+
+ ptr = buf;
+
+ while (bytes > 0) {
+
+ UINT8 byte = *ptr;
+
+ ptr++;
+ bytes--;
+
+ /* get a byte from the input stream and insert in the bit buffer */
+ if (bitstate->fill&1)
+ /* fill MSB first */
+ bitstate->bitbuffer |= (unsigned long) byte << bitstate->bitcount;
+ else
+ /* fill LSB first */
+ bitstate->bitbuffer = (bitstate->bitbuffer << 8) | byte;
+
+ bitstate->bitcount += 8;
+
+ while (bitstate->bitcount >= bitstate->bits) {
+
+ /* get a pixel from the bit buffer */
+ unsigned long data;
+ FLOAT32 pixel;
+
+ if (bitstate->fill&2) {
+ /* store LSB first */
+ data = bitstate->bitbuffer & bitstate->mask;
+ if (bitstate->bitcount > 32)
+ /* bitbuffer overflow; restore it from last input byte */
+ bitstate->bitbuffer = byte >> (8 - (bitstate->bitcount -
+ bitstate->bits));
+ else
+ bitstate->bitbuffer >>= bitstate->bits;
+ } else
+ /* store MSB first */
+ data = (bitstate->bitbuffer >> (bitstate->bitcount -
+ bitstate->bits))
+ & bitstate->mask;
+
+ bitstate->bitcount -= bitstate->bits;
+
+ if (bitstate->lutsize > 0) {
+ /* map through lookup table */
+ if (data <= 0)
+ pixel = bitstate->lut[0];
+ else if (data >= bitstate->lutsize)
+ pixel = bitstate->lut[bitstate->lutsize-1];
+ else
+ pixel = bitstate->lut[data];
+ } else {
+ /* convert */
+ if (data & bitstate->signmask)
+ /* image memory contains signed data */
+ pixel = (FLOAT32) (INT32) (data | ~bitstate->mask);
+ else
+ pixel = (FLOAT32) data;
+ }
+
+ *(FLOAT32*)(&im->image32[state->y][state->x]) = pixel;
+
+ /* step forward */
+ if (++state->x >= state->xsize) {
+ /* 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 */
+ if (bitstate->pad > 0)
+ bitstate->bitcount = 0;
+ }
+ }
+ }
+
+ return ptr - buf;
+}