Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Imaging/libImaging/TgaRleDecode.c
diff options
context:
space:
mode:
Diffstat (limited to 'Imaging/libImaging/TgaRleDecode.c')
-rw-r--r--Imaging/libImaging/TgaRleDecode.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/Imaging/libImaging/TgaRleDecode.c b/Imaging/libImaging/TgaRleDecode.c
new file mode 100644
index 0000000..1011f0d
--- /dev/null
+++ b/Imaging/libImaging/TgaRleDecode.c
@@ -0,0 +1,118 @@
+/*
+ * The Python Imaging Library.
+ * $Id: TgaRleDecode.c 2134 2004-10-06 08:55:20Z fredrik $
+ *
+ * decoder for Targa RLE data.
+ *
+ * history:
+ * 97-01-04 fl created
+ * 98-09-11 fl don't one byte per pixel; take orientation into account
+ *
+ * Copyright (c) Fredrik Lundh 1997.
+ * Copyright (c) Secret Labs AB 1997-98.
+ *
+ * See the README file for information on usage and redistribution.
+ */
+
+
+#include "Imaging.h"
+
+
+int
+ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
+ UINT8* buf, int bytes)
+{
+ int n, depth;
+ UINT8* ptr;
+
+ ptr = buf;
+
+ if (state->state == 0) {
+
+ /* check image orientation */
+ if (state->ystep < 0) {
+ state->y = state->ysize-1;
+ state->ystep = -1;
+ } else
+ state->ystep = 1;
+
+ state->state = 1;
+
+ }
+
+ depth = state->count;
+
+ for (;;) {
+
+ if (bytes < 1)
+ return ptr - buf;
+
+ if (ptr[0] & 0x80) {
+
+ /* Run (1 + pixelsize bytes) */
+
+ if (bytes < 1 + depth)
+ break;
+
+ n = depth * ((ptr[0] & 0x7f) + 1);
+
+ if (state->x + n > state->bytes) {
+ state->errcode = IMAGING_CODEC_OVERRUN;
+ return -1;
+ }
+
+ if (depth == 1)
+ memset(state->buffer + state->x, ptr[1], n);
+ else {
+ int i;
+ for (i = 0; i < n; i += depth)
+ memcpy(state->buffer + state->x + i, ptr+1, depth);
+ }
+
+ ptr += 1 + depth;
+ bytes -= 1 + depth;
+
+ } else {
+
+ /* Literal (1+n+1 bytes block) */
+ n = depth * (ptr[0] + 1);
+
+ if (bytes < 1 + n)
+ break;
+
+ if (state->x + n > state->bytes) {
+ state->errcode = IMAGING_CODEC_OVERRUN;
+ return -1;
+ }
+
+ memcpy(state->buffer + state->x, ptr + 1, n);
+
+ ptr += 1 + n;
+ bytes -= 1 + n;
+
+ }
+
+ state->x += n;
+
+ if (state->x >= state->bytes) {
+
+ /* Got a full line, unpack it */
+ state->shuffle((UINT8*) im->image[state->y + state->yoff] +
+ state->xoff * im->pixelsize, state->buffer,
+ state->xsize);
+
+ state->x = 0;
+
+ state->y += state->ystep;
+
+ if (state->y < 0 || state->y >= state->ysize) {
+ /* End of file (errcode = 0) */
+ return -1;
+ }
+
+ }
+
+ }
+
+ return ptr - buf;
+}