Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Imaging/libImaging/PcxEncode.c
diff options
context:
space:
mode:
Diffstat (limited to 'Imaging/libImaging/PcxEncode.c')
-rw-r--r--Imaging/libImaging/PcxEncode.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/Imaging/libImaging/PcxEncode.c b/Imaging/libImaging/PcxEncode.c
new file mode 100644
index 0000000..2c9d250
--- /dev/null
+++ b/Imaging/libImaging/PcxEncode.c
@@ -0,0 +1,148 @@
+/*
+ * The Python Imaging Library.
+ * $Id: PcxEncode.c 2134 2004-10-06 08:55:20Z fredrik $
+ *
+ * encoder for PCX data
+ *
+ * history:
+ * 99-02-07 fl created
+ *
+ * Copyright (c) Fredrik Lundh 1999.
+ * Copyright (c) Secret Labs AB 1999.
+ *
+ * See the README file for information on usage and redistribution.
+ */
+
+
+#include "Imaging.h"
+
+enum { INIT, FETCH, ENCODE };
+
+/* we're reusing "ystep" to store the last value */
+#define LAST ystep
+
+int
+ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
+{
+ UINT8* ptr;
+ int this;
+
+ ptr = buf;
+
+ if (!state->state) {
+
+ /* sanity check */
+ if (state->xsize <= 0 || state->ysize <= 0) {
+ state->errcode = IMAGING_CODEC_END;
+ return 0;
+ }
+
+ state->bytes = (state->xsize*state->bits + 7) / 8;
+ state->state = FETCH;
+
+ }
+
+ for (;;)
+
+ switch (state->state) {
+ case FETCH:
+
+ /* get a line of data */
+ if (state->y >= state->ysize) {
+ state->errcode = IMAGING_CODEC_END;
+ return ptr - buf;
+ }
+
+ state->shuffle(state->buffer,
+ (UINT8*) im->image[state->y + state->yoff] +
+ state->xoff * im->pixelsize, state->xsize);
+
+ state->y++;
+
+ state->count = 1;
+ state->LAST = state->buffer[0];
+
+ state->x = 1;
+
+ state->state = ENCODE;
+ /* fall through */
+
+ case ENCODE:
+
+ /* compress this line */
+
+ /* when we arrive here, "count" contains the number of
+ bytes having the value of "LAST" that we've already
+ seen */
+
+ while (state->x < state->bytes) {
+
+ if (state->count == 63) {
+
+ /* this run is full; flush it */
+ if (bytes < 2)
+ return ptr - buf;
+ *ptr++ = 0xff;
+ *ptr++ = state->LAST;
+ bytes -= 2;
+
+ state->count = 0;
+
+ }
+
+ this = state->buffer[state->x];
+
+ if (this == state->LAST) {
+
+ /* extend the current run */
+ state->x++;
+ state->count++;
+
+ } else {
+
+ /* start a new run */
+ if (state->count == 1 && (state->LAST < 0xc0)) {
+ if (bytes < 1)
+ return ptr - buf;
+ *ptr++ = state->LAST;
+ bytes--;
+ } else {
+ if (state->count > 0) {
+ if (bytes < 2)
+ return ptr - buf;
+ *ptr++ = 0xc0 | state->count;
+ *ptr++ = state->LAST;
+ bytes -= 2;
+ }
+ }
+
+ state->LAST = this;
+ state->count = 1;
+
+ state->x++;
+
+ }
+ }
+
+ /* end of line; flush the current run */
+ if (state->count == 1 && (state->LAST < 0xc0)) {
+ if (bytes < 1)
+ return ptr - buf;
+ *ptr++ = state->LAST;
+ bytes--;
+ } else {
+ if (state->count > 0) {
+ if (bytes < 2)
+ return ptr - buf;
+ *ptr++ = 0xc0 | state->count;
+ *ptr++ = state->LAST;
+ bytes -= 2;
+ }
+ }
+
+ /* read next line */
+ state->state = FETCH;
+ break;
+
+ }
+}