diff options
author | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
commit | f4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch) | |
tree | 2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/lib/lbxutil/image/dfaxg42d.c | |
parent | a840692edc9c6d19cd7c057f68e39c7d95eb767d (diff) | |
download | nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2 nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip |
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz
Keywords:
Imported nx-X11-3.1.0-1.tar.gz
into Git repository
Diffstat (limited to 'nx-X11/lib/lbxutil/image/dfaxg42d.c')
-rw-r--r-- | nx-X11/lib/lbxutil/image/dfaxg42d.c | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/nx-X11/lib/lbxutil/image/dfaxg42d.c b/nx-X11/lib/lbxutil/image/dfaxg42d.c new file mode 100644 index 000000000..609992d62 --- /dev/null +++ b/nx-X11/lib/lbxutil/image/dfaxg42d.c @@ -0,0 +1,420 @@ +/* $Xorg: dfaxg42d.c,v 1.3 2000/08/17 19:46:40 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. + */ +/* $XFree86: xc/lib/lbxutil/image/dfaxg42d.c,v 1.5 2001/01/17 19:43:35 dawes Exp $ */ + +#include <X11/Xos.h> +#include <X11/Xfuncproto.h> +#include <X11/Xfuncs.h> +#include <stdlib.h> +#include "g3states.h" +#include "lbxfax.h" +#include <X11/extensions/lbximage.h> + +/* + * ------------------------------------------------------------------------- + * FAX G42D decoding for 1 bit images + * ------------------------------------------------------------------------- + */ + +static short sp_data, sp_bit; + + +/* + * Fetch a byte from the input stream + */ + +static unsigned char +fetchByte (unsigned char **inbuf) + +{ + unsigned char byte = **inbuf; + (*inbuf)++; + return (byte); +} + + +/* + * Decode a run of white. + */ + +static int +decode_white_run (unsigned char **inbuf) + +{ + short state = sp_bit; + short action; + int runlen = 0; + + for (;;) + { + if (sp_bit == 0) + { + nextbyte: + sp_data = fetchByte (inbuf); + } + + action = TIFFFax1DAction[state][sp_data]; + state = TIFFFax1DNextState[state][sp_data]; + if (action == ACT_INCOMP) + goto nextbyte; + if (action == ACT_INVALID) + return (G3CODE_INVALID); + if (action == ACT_EOL) + return (G3CODE_EOL); + sp_bit = state; + action = RUNLENGTH(action - ACT_WRUNT); + runlen += action; + if (action < 64) + return (runlen); + } +} + + +/* + * Decode a run of black. + */ + +static int +decode_black_run (unsigned char **inbuf) + +{ + short state = sp_bit + 8; + short action; + int runlen = 0; + + for (;;) + { + if (sp_bit == 0) + { + nextbyte: + sp_data = fetchByte (inbuf); + } + + action = TIFFFax1DAction[state][sp_data]; + state = TIFFFax1DNextState[state][sp_data]; + if (action == ACT_INCOMP) + goto nextbyte; + if (action == ACT_INVALID) + return (G3CODE_INVALID); + if (action == ACT_EOL) + return (G3CODE_EOL); + sp_bit = state; + action = RUNLENGTH(action - ACT_BRUNT); + runlen += action; + if (action < 64) + return (runlen); + state += 8; + } +} + + +/* + * Return the next uncompressed mode code word. + */ + +static int +decode_uncomp_code (unsigned char **inbuf) + +{ + short code; + + do { + if (sp_bit == 0 || sp_bit > 7) + sp_data = fetchByte (inbuf); + + code = TIFFFaxUncompAction[sp_bit][sp_data]; + sp_bit = TIFFFaxUncompNextState[sp_bit][sp_data]; + } while (code == ACT_INCOMP); + + return (code); +} + + +/* + * Fill a span with ones. + */ + +static void +fillspan (char *cp, + int x, int count) + +{ + static unsigned char masks[] = + { 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; + + if (count <= 0) + return; + + cp += x>>3; + + if (x &= 7) + { + /* align to byte boundary */ + + if (count < 8 - x) { + *cp++ |= masks[count] >> x; + return; + } + + *cp++ |= 0xff >> x; + count -= 8 - x; + } + + while (count >= 8) + { + *cp++ = (char)0xff; + count -= 8; + } + + *cp |= masks[count]; +} + + +/* + * Return the next bit in the input stream. This is + * used to extract 2D tag values and the color tag + * at the end of a terminating uncompressed data code. + */ + +static int +nextbit (unsigned char **inbuf) + +{ + static unsigned char bitMask[8] = + { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + int bit; + + if (sp_bit == 0) + sp_data = fetchByte (inbuf); + + bit = sp_data & bitMask[sp_bit]; + + if (++(sp_bit) > 7) + sp_bit = 0; + + return (bit); +} + + +static int +DecodeFaxG42D (unsigned char **inbuf, + unsigned char *refline, + int pixels_per_line, + unsigned char *outbuf) + +{ + int a0 = -1; + int b1, b2; + int run1, run2; /* for horizontal mode */ + short mode; + short color = 1; + + do { + if (sp_bit == 0 || sp_bit > 7) + sp_data = fetchByte (inbuf); + + mode = TIFFFax2DMode[sp_bit][sp_data]; + sp_bit = TIFFFax2DNextState[sp_bit][sp_data]; + + switch (mode) + { + case MODE_NULL: + break; + + case MODE_PASS: + b2 = LbxImageFindDiff (refline, a0, pixels_per_line, !color); + b1 = LbxImageFindDiff (refline, b2, pixels_per_line, color); + b2 = LbxImageFindDiff (refline, b1, pixels_per_line, !color); + + if (color) + { + if (a0 < 0) + a0 = 0; + fillspan ((char *) outbuf, a0, b2 - a0); + } + + a0 = b2; + break; + + case MODE_HORIZ: + if (color == 1) + { + run1 = decode_white_run (inbuf); + run2 = decode_black_run (inbuf); + } + else + { + run1 = decode_black_run (inbuf); + run2 = decode_white_run (inbuf); + } + + /* + * Do the appropriate fill. Note that we exit this logic with + * the same color that we enter with since we do 2 fills. This + * explains the somewhat obscure logic below. + */ + + if (a0 < 0) + a0 = 0; + if (a0 + run1 > pixels_per_line) + run1 = pixels_per_line - a0; + if (color) + fillspan ((char *) outbuf, a0, run1); + a0 += run1; + if (a0 + run2 > pixels_per_line) + run2 = pixels_per_line - a0; + if (!color) + fillspan ((char *) outbuf, a0, run2); + a0 += run2; + break; + + case MODE_VERT_V0: + case MODE_VERT_VR1: + case MODE_VERT_VR2: + case MODE_VERT_VR3: + case MODE_VERT_VL1: + case MODE_VERT_VL2: + case MODE_VERT_VL3: + b2 = LbxImageFindDiff (refline, a0, pixels_per_line, !color); + b1 = LbxImageFindDiff (refline, b2, pixels_per_line, color); + b1 += mode - MODE_VERT_V0; + + if (color) + { + if (a0 < 0) + a0 = 0; + fillspan ((char *) outbuf, a0, b1 - a0); + } + + color = !color; + a0 = b1; + break; + + case MODE_UNCOMP: + /* + * Uncompressed mode: select from the special set of code words. + */ + + if (a0 < 0) + a0 = 0; + do + { + mode = decode_uncomp_code (inbuf); + switch (mode) + { + case UNCOMP_RUN1: + case UNCOMP_RUN2: + case UNCOMP_RUN3: + case UNCOMP_RUN4: + case UNCOMP_RUN5: + run1 = mode - UNCOMP_RUN0; + fillspan ((char *) outbuf, a0+run1-1, 1); + a0 += run1; + break; + + case UNCOMP_RUN6: + a0 += 5; + break; + + case UNCOMP_TRUN0: + case UNCOMP_TRUN1: + case UNCOMP_TRUN2: + case UNCOMP_TRUN3: + case UNCOMP_TRUN4: + + run1 = mode - UNCOMP_TRUN0; + a0 += run1; + color = nextbit (inbuf) ? 0 : 1; + break; + + case UNCOMP_INVALID: + goto bad; + + case UNCOMP_EOF: + return (0); + } + } while (mode < UNCOMP_EXIT); + break; + + case MODE_ERROR_1: + /* fall thru... */ + case MODE_ERROR: + goto bad; + + default: + return (0); + } + + } while (a0 < pixels_per_line); + +bad: + return (a0 >= pixels_per_line); +} + + +int +LbxImageDecodeFaxG42D (unsigned char *inbuf, + unsigned char *outbuf, + int image_bytes, + int pixels_per_line, + int padded_bytes_per_scanline, + int reverse_bits) + +{ + int bytes_per_scanline = ROUNDUP8 (pixels_per_line); + unsigned char *refline, *refptr; + unsigned char *outbuf_start = outbuf; + int bytes_left = image_bytes; + int i; + + refline = (unsigned char *) malloc (bytes_per_scanline + 1); + refptr = refline + 1; + + for (i = 0; i < bytes_per_scanline + 1; i++) + refline[i] = 0xff; + + bzero (outbuf, image_bytes); + + sp_bit = 0; + sp_data = 0; + + while (bytes_left > 0) + { + if (!DecodeFaxG42D (&inbuf, refptr, pixels_per_line, outbuf)) + return (0); + + memcpy (refptr, outbuf, bytes_per_scanline); + + outbuf += padded_bytes_per_scanline; + bytes_left -= padded_bytes_per_scanline; + } + + free ((char *) refline); + + if (reverse_bits) + LbxReverseBits (outbuf_start, image_bytes); + + return (outbuf - outbuf_start); +} |