diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:40 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:40 +0000 |
commit | c16c03b7f3122a65027dd5ac06fee18455dcdee9 (patch) | |
tree | 0ed3fbfcc59c3dabba89e52f17d3600594dc0823 /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.c | 207 |
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); +} |