aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/lbxutil/image/dfaxg42d.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/lib/lbxutil/image/dfaxg42d.c')
-rw-r--r--nx-X11/lib/lbxutil/image/dfaxg42d.c420
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);
+}