summaryrefslogtreecommitdiff
path: root/src/image/epackbits.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:40 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:40 +0000
commitc16c03b7f3122a65027dd5ac06fee18455dcdee9 (patch)
tree0ed3fbfcc59c3dabba89e52f17d3600594dc0823 /src/image/epackbits.c
R6.6 is the Xorg base-lineXORG-MAINXORG-STABLE
Diffstat (limited to 'src/image/epackbits.c')
-rw-r--r--src/image/epackbits.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/image/epackbits.c b/src/image/epackbits.c
new file mode 100644
index 0000000..1ceed56
--- /dev/null
+++ b/src/image/epackbits.c
@@ -0,0 +1,207 @@
+/* $Xorg: epackbits.c,v 1.4 2000/08/17 19:46:41 cpqbld Exp $ */
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
+ * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <X11/Xfuncproto.h>
+#include "lbximage.h"
+
+/*
+ * -------------------------------------------------------------------------
+ * PackBits encoding for 8 bit color images
+ * -------------------------------------------------------------------------
+ */
+
+#define PutByte(byte,bufptr,bytesLeft) \
+{ \
+ if (*bytesLeft < 1) {\
+ *outbuf = outptr; \
+ return (0); \
+ } \
+ *bufptr++ = byte; \
+ (*bytesLeft)--; \
+}
+
+
+static int
+EncodePackBits (inbuf, numPixels, outbuf, bytesLeft)
+
+char *inbuf;
+int numPixels;
+char **outbuf;
+int *bytesLeft;
+
+{
+ register int pixelsLeft = numPixels;
+ register char *outptr = *outbuf;
+ register char *lastliteral;
+ register int n, b;
+ enum { BASE, LITERAL, RUN, LITERAL_RUN } state;
+
+ state = BASE;
+ lastliteral = 0;
+
+ while (pixelsLeft > 0)
+ {
+ /*
+ * Find the longest string of identical bytes.
+ */
+
+ b = *inbuf++, pixelsLeft--, n = 1;
+ for (; pixelsLeft > 0 && b == *inbuf; pixelsLeft--, inbuf++)
+ n++;
+
+ again:
+
+ switch (state)
+ {
+ case BASE: /* initial state, set run/literal */
+ if (n > 1)
+ {
+ state = RUN;
+
+ if (n > 128)
+ {
+ PutByte (-127, outptr, bytesLeft);
+ PutByte (b, outptr, bytesLeft);
+ n -= 128;
+ goto again;
+ }
+
+ PutByte (-(n-1), outptr, bytesLeft);
+ PutByte (b, outptr, bytesLeft);
+ }
+ else
+ {
+ lastliteral = outptr;
+ PutByte (0, outptr, bytesLeft);
+ PutByte (b, outptr, bytesLeft);
+ state = LITERAL;
+ }
+
+ break;
+
+ case LITERAL: /* last object was literal string */
+ if (n > 1)
+ {
+ state = LITERAL_RUN;
+
+ if (n > 128)
+ {
+ PutByte (-127, outptr, bytesLeft);
+ PutByte (b, outptr, bytesLeft);
+ n -= 128;
+ goto again;
+ }
+
+ PutByte (-(n-1), outptr, bytesLeft); /* encode run */
+ PutByte (b, outptr, bytesLeft);
+ }
+ else
+ { /* extend literal */
+ if (++(*lastliteral) == 127)
+ state = BASE;
+ PutByte (b, outptr, bytesLeft);
+ }
+
+ break;
+
+ case RUN: /* last object was run */
+ if (n > 1)
+ {
+ if (n > 128)
+ {
+ PutByte (-127, outptr, bytesLeft);
+ PutByte (b, outptr, bytesLeft);
+ n -= 128;
+ goto again;
+ }
+ PutByte (-(n-1), outptr, bytesLeft);
+ PutByte (b, outptr, bytesLeft);
+ }
+ else
+ {
+ lastliteral = outptr;
+ PutByte (0, outptr, bytesLeft);
+ PutByte (b, outptr, bytesLeft);
+ state = LITERAL;
+ }
+
+ break;
+
+ case LITERAL_RUN: /* literal followed by a run */
+ /*
+ * Check to see if previous run should
+ * be converted to a literal, in which
+ * case we convert literal-run-literal
+ * to a single literal.
+ */
+
+ if (n == 1 && outptr[-2] == (char)-1 && *lastliteral < 126)
+ {
+ state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL);
+ outptr[-2] = outptr[-1]; /* replicate */
+ }
+ else
+ state = RUN;
+ goto again;
+ }
+ }
+
+ *outbuf = outptr;
+
+ return (1);
+}
+
+
+int
+LbxImageEncodePackBits (inbuf, outbuf, outbufSize, format, depth,
+ num_scan_lines, scan_line_size, bytesCompressed)
+
+char *inbuf;
+char *outbuf;
+int outbufSize;
+int format;
+int depth;
+int num_scan_lines;
+int scan_line_size;
+int *bytesCompressed;
+
+{
+ char *outbuf_start = outbuf;
+ int padded_scan_line_size = (scan_line_size % 4) ?
+ scan_line_size + (4 - scan_line_size % 4) : scan_line_size;
+ int bytesLeft = outbufSize;
+
+ while (num_scan_lines > 0)
+ {
+ if (!EncodePackBits (inbuf, scan_line_size, &outbuf, &bytesLeft))
+ return (LBX_IMAGE_COMPRESS_NOT_WORTH_IT);
+
+ inbuf += padded_scan_line_size;
+ num_scan_lines--;
+ }
+
+ *bytesCompressed = outbuf - outbuf_start;
+ return (LBX_IMAGE_COMPRESS_SUCCESS);
+}