awips2/pythonPackages/pil/libImaging/ZipDecode.c
root 133dc97f67 Initial revision of AWIPS2 11.9.0-7p5
Former-commit-id: 06a8b51d6d [formerly 9f19e3f712 [formerly 64fa9254b946eae7e61bbc3f513b7c3696c4f54f]]
Former-commit-id: 9f19e3f712
Former-commit-id: a02aeb236c
2012-01-06 08:55:05 -06:00

208 lines
5.1 KiB
C

/*
* The Python Imaging Library.
* $Id: ZipDecode.c 2134 2004-10-06 08:55:20Z fredrik $
*
* decoder for ZIP (deflated) image data.
*
* history:
* 1996-12-14 fl Created (for PNG)
* 1997-01-15 fl Prepared to read TIFF/ZIP
* 2001-11-19 fl PNG incomplete read patch (from Bernhard Herzog)
*
* Copyright (c) Fredrik Lundh 1996.
* Copyright (c) Secret Labs AB 1997-2001.
*
* See the README file for information on usage and redistribution.
*/
#include "Imaging.h"
#ifdef HAVE_LIBZ
#include "Zip.h"
/* -------------------------------------------------------------------- */
/* Decoder */
/* -------------------------------------------------------------------- */
int
ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
{
ZIPSTATE* context = (ZIPSTATE*) state->context;
int err;
int n;
UINT8* ptr;
int i, bpp;
if (!state->state) {
/* Initialization */
if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE)
context->prefix = 1; /* PNG */
/* Expand standard buffer to make room for the (optional) filter
prefix, and allocate a buffer to hold the previous line */
free(state->buffer);
state->buffer = (UINT8*) malloc(state->bytes+1);
context->previous = (UINT8*) malloc(state->bytes+1);
if (!state->buffer || !context->previous) {
state->errcode = IMAGING_CODEC_MEMORY;
return -1;
}
context->last_output = 0;
/* Initialize to black */
memset(context->previous, 0, state->bytes+1);
/* Setup decompression context */
context->z_stream.zalloc = (alloc_func)0;
context->z_stream.zfree = (free_func)0;
context->z_stream.opaque = (voidpf)0;
err = inflateInit(&context->z_stream);
if (err < 0) {
state->errcode = IMAGING_CODEC_CONFIG;
return -1;
}
/* Ready to decode */
state->state = 1;
}
/* Setup the source buffer */
context->z_stream.next_in = buf;
context->z_stream.avail_in = bytes;
/* Decompress what we've got this far */
while (context->z_stream.avail_in > 0) {
context->z_stream.next_out = state->buffer + context->last_output;
context->z_stream.avail_out =
state->bytes + context->prefix - context->last_output;
err = inflate(&context->z_stream, Z_NO_FLUSH);
if (err < 0) {
/* Something went wrong inside the compression library */
if (err == Z_DATA_ERROR)
state->errcode = IMAGING_CODEC_BROKEN;
else if (err == Z_MEM_ERROR)
state->errcode = IMAGING_CODEC_MEMORY;
else
state->errcode = IMAGING_CODEC_CONFIG;
free(context->previous);
inflateEnd(&context->z_stream);
return -1;
}
n = state->bytes + context->prefix - context->z_stream.avail_out;
if (n < state->bytes + context->prefix) {
context->last_output = n;
break; /* need more input data */
}
/* Apply predictor */
switch (context->mode) {
case ZIP_PNG:
switch (state->buffer[0]) {
case 0:
break;
case 1:
/* prior */
bpp = (state->bits + 7) / 8;
for (i = bpp+1; i <= state->bytes; i++)
state->buffer[i] += state->buffer[i-bpp];
break;
case 2:
/* up */
for (i = 1; i <= state->bytes; i++)
state->buffer[i] += context->previous[i];
break;
case 3:
/* average */
bpp = (state->bits + 7) / 8;
for (i = 1; i <= bpp; i++)
state->buffer[i] += context->previous[i]/2;
for (; i <= state->bytes; i++)
state->buffer[i] +=
(state->buffer[i-bpp] + context->previous[i])/2;
break;
case 4:
/* paeth filtering */
bpp = (state->bits + 7) / 8;
for (i = 1; i <= bpp; i++)
state->buffer[i] += context->previous[i];
for (; i <= state->bytes; i++) {
int a, b, c;
int pa, pb, pc;
/* fetch pixels */
a = state->buffer[i-bpp];
b = context->previous[i];
c = context->previous[i-bpp];
/* distances to surrounding pixels */
pa = abs(b - c);
pb = abs(a - c);
pc = abs(a + b - 2*c);
/* pick predictor with the shortest distance */
state->buffer[i] +=
(pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
}
break;
default:
state->errcode = IMAGING_CODEC_UNKNOWN;
free(context->previous);
inflateEnd(&context->z_stream);
return -1;
}
break;
case ZIP_TIFF_PREDICTOR:
bpp = (state->bits + 7) / 8;
for (i = bpp+1; i <= state->bytes; i++)
state->buffer[i] += state->buffer[i-bpp];
break;
}
/* Stuff data into the image */
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
state->xoff * im->pixelsize,
state->buffer + context->prefix,
state->xsize);
state->y++;
/* all inflate output has been consumed */
context->last_output = 0;
if (state->y >= state->ysize || err == Z_STREAM_END) {
/* The image and the data should end simultaneously */
/* if (state->y < state->ysize || err != Z_STREAM_END)
state->errcode = IMAGING_CODEC_BROKEN; */
free(context->previous);
inflateEnd(&context->z_stream);
return -1; /* end of file (errcode=0) */
}
/* Swap buffer pointers */
ptr = state->buffer;
state->buffer = context->previous;
context->previous = ptr;
}
return bytes; /* consumed all of it */
}
#endif