diff options
Diffstat (limited to 'nx-X11/lib/lbxutil/image/epackbits.c')
-rw-r--r-- | nx-X11/lib/lbxutil/image/epackbits.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/nx-X11/lib/lbxutil/image/epackbits.c b/nx-X11/lib/lbxutil/image/epackbits.c new file mode 100644 index 000000000..816fee57a --- /dev/null +++ b/nx-X11/lib/lbxutil/image/epackbits.c @@ -0,0 +1,202 @@ +/* $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 <X11/extensions/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 (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 (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); +} |