Pillow/libImaging/SunRleDecode.c

131 lines
2.7 KiB
C
Raw Normal View History

2010-07-31 06:52:47 +04:00
/*
* THIS IS WORK IN PROGRESS
*
* The Python Imaging Library.
* $Id$
*
* decoder for SUN RLE data.
*
* history:
* 97-01-04 fl Created
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"
int
ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
{
int n;
UINT8* ptr;
UINT8 extra_data = 0;
UINT8 extra_bytes = 0;
int ct_bytes = 0;
2010-07-31 06:52:47 +04:00
ptr = buf;
for (;;) {
if (bytes < 1)
return ptr - buf;
2010-07-31 06:52:47 +04:00
if (ptr[0] == 0x80) {
2010-07-31 06:52:47 +04:00
if (bytes < 2)
break;
2010-07-31 06:52:47 +04:00
n = ptr[1];
2010-07-31 06:52:47 +04:00
if (n == 0) {
2010-07-31 06:52:47 +04:00
/* Literal 0x80 (2 bytes) */
n = 1;
ct_bytes += n;
2010-07-31 06:52:47 +04:00
state->buffer[state->x] = 0x80;
2010-07-31 06:52:47 +04:00
ptr += 2;
bytes -= 2;
2010-07-31 06:52:47 +04:00
} else {
2010-07-31 06:52:47 +04:00
/* Run (3 bytes) */
if (bytes < 3)
break;
2010-07-31 06:52:47 +04:00
ct_bytes += n;
if (state->x + n > state->bytes) {
extra_bytes = n; /* full value */
n = state->bytes - state->x;
extra_bytes -= n;
extra_data = ptr[2];
}
2010-07-31 06:52:47 +04:00
memset(state->buffer + state->x, ptr[2], n);
2010-07-31 06:52:47 +04:00
ptr += 3;
bytes -= 3;
2010-07-31 06:52:47 +04:00
}
2010-07-31 06:52:47 +04:00
} else {
2010-07-31 06:52:47 +04:00
/* Literal byte */
n = 1;
ct_bytes += n;
2010-07-31 06:52:47 +04:00
state->buffer[state->x] = ptr[0];
2010-07-31 06:52:47 +04:00
ptr += 1;
bytes -= 1;
2010-07-31 06:52:47 +04:00
}
2010-07-31 06:52:47 +04:00
for (;;) {
state->x += n;
if (state->x >= state->bytes) {
2010-07-31 06:52:47 +04:00
/* Got a full line, unpack it */
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->buffer,
state->xsize);
2010-07-31 06:52:47 +04:00
state->x = 0;
2010-07-31 06:52:47 +04:00
if (++state->y >= state->ysize) {
/* End of file (errcode = 0) */
printf("%d", ct_bytes);
return -1;
}
}
if (extra_bytes == 0) {
break;
}
2010-07-31 06:52:47 +04:00
if (state->x > 0) {
break; // assert
}
2010-07-31 06:52:47 +04:00
if (extra_bytes >= state->bytes) {
n = state->bytes;
} else {
n = extra_bytes;
}
memset(state->buffer + state->x, extra_data, n);
extra_bytes -= n;
}
2010-07-31 06:52:47 +04:00
}
return ptr - buf;
}