diff options
Diffstat (limited to 'nx-X11/lib/lbxutil/image/efaxg42d.c')
-rw-r--r-- | nx-X11/lib/lbxutil/image/efaxg42d.c | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/nx-X11/lib/lbxutil/image/efaxg42d.c b/nx-X11/lib/lbxutil/image/efaxg42d.c new file mode 100644 index 000000000..a89b5e0d2 --- /dev/null +++ b/nx-X11/lib/lbxutil/image/efaxg42d.c @@ -0,0 +1,328 @@ +/* $Xorg: efaxg42d.c,v 1.3 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. + */ +/* $XFree86: xc/lib/lbxutil/image/efaxg42d.c,v 1.4 2001/01/17 19:43:35 dawes Exp $ */ + +#include <X11/Xos.h> +#include <X11/Xfuncproto.h> +#include <stdlib.h> +#include "lbxfax.h" +#include <X11/extensions/lbximage.h> +#include "lbxbwcodes.h" + +/* + * ------------------------------------------------------------------------- + * FAX G42D encoding for 1 bit images + * ------------------------------------------------------------------------- + */ + +static short sp_data, sp_bit; + +static tableentry horizcode = + { 3, 0x1 }; /* 001 */ + +static tableentry passcode = + { 4, 0x1 }; /* 0001 */ + +static tableentry vcodes[7] = { + { 7, 0x03 }, /* 0000 011 */ + { 6, 0x03 }, /* 0000 11 */ + { 3, 0x03 }, /* 011 */ + { 1, 0x1 }, /* 1 */ + { 3, 0x2 }, /* 010 */ + { 6, 0x02 }, /* 0000 10 */ + { 7, 0x02 } /* 0000 010 */ +}; + +typedef struct { + unsigned char *bufStart; + unsigned char *bufPtr; + int bufSize; + int bytesLeft; +} Buffer; + + + +/* + * Flush bits to output buffer. + */ + +static int +flushbits (Buffer *outbuf) + +{ + if (outbuf->bytesLeft > 0) + { + *(outbuf->bufPtr++) = sp_data; + outbuf->bytesLeft--; + + sp_data = 0; + sp_bit = 8; + + return (1); + } + else + return (0); +} + + +/* + * Write a variable-length bit-value to the output stream. Values are + * assumed to be at most 16 bits. + */ + +static int +putbits (unsigned int bits, + unsigned int length, + Buffer *outbuf) + +{ + static int mask[9] = + {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; + + while (length > sp_bit) + { + sp_data |= bits >> (length - sp_bit); + length -= sp_bit; + if (!flushbits (outbuf)) + return (0); + } + + sp_data |= (bits & mask[length]) << (sp_bit - length); + sp_bit -= length; + + if (sp_bit == 0) + { + if (!flushbits (outbuf)) + return (0); + } + + return (1); +} + + +/* + * Write a code to the output stream. + */ + +static int +putcode (tableentry *te, + Buffer *outbuf) + +{ + return (putbits (te->code, te->length, outbuf)); +} + + +/* + * Write the sequence of codes that describes the specified span of + * zero's or one's. The appropriate table that holds the make-up and + * terminating codes is supplied. + */ + +static int +putspan (int span, + tableentry *tab, + Buffer *outbuf) + +{ + while (span >= 2624) + { + tableentry *te = &tab[63 + (2560 >> 6)]; + if (!putcode (te, outbuf)) + return (0); + span -= te->runlen; + } + + if (span >= 64) + { + tableentry *te = &tab[63 + (span >> 6)]; + if (!putcode (te, outbuf)) + return (0); + span -= te->runlen; + } + + if (!putcode (&tab[span], outbuf)) + return (0); + + return (1); +} + + + +#define PIXEL(buf,ix) ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1) + +static int +EncodeFaxG42D (unsigned char *inbuf, + unsigned char *refline, + int bits, + Buffer *outbuf) + +{ + short white = 1; + int a0 = 0; + int a1 = (PIXEL (inbuf, 0) != white ? + 0 : LbxImageFindDiff (inbuf, 0, bits, white)); + int b1 = (PIXEL (refline, 0) != white ? + 0 : LbxImageFindDiff (refline, 0, bits, white)); + int a2, b2; + + for (;;) + { + b2 = LbxImageFindDiff (refline, b1, bits, PIXEL (refline, b1)); + if (b2 >= a1) + { + int d = b1 - a1; + if (!(-3 <= d && d <= 3)) + { + /* horizontal mode */ + + a2 = LbxImageFindDiff (inbuf, a1, bits, PIXEL (inbuf, a1)); + if (!putcode (&horizcode, outbuf)) + return (0); + + if (a0 + a1 == 0 || PIXEL (inbuf, a0) == white) + { + if (!putspan(a1 - a0, TIFFFaxWhiteCodes, outbuf)) + return (0); + if (!putspan(a2 - a1, TIFFFaxBlackCodes, outbuf)) + return (0); + } + else + { + if (!putspan (a1 - a0, TIFFFaxBlackCodes, outbuf)) + return (0); + if (!putspan (a2 - a1, TIFFFaxWhiteCodes, outbuf)) + return (0); + } + + a0 = a2; + } + else + { + /* vertical mode */ + + if (!putcode (&vcodes[d+3], outbuf)) + return (0); + a0 = a1; + } + } + else + { + /* pass mode */ + + if (!putcode (&passcode, outbuf)) + return (0); + a0 = b2; + } + + if (a0 >= bits) + break; + + a1 = LbxImageFindDiff (inbuf, a0, bits, PIXEL (inbuf, a0)); + b1 = LbxImageFindDiff (refline, a0, bits, !PIXEL (inbuf, a0)); + b1 = LbxImageFindDiff (refline, b1, bits, PIXEL (inbuf, a0)); + } + + return (1); +} + + +int +LbxImageEncodeFaxG42D (unsigned char *inbuf, + unsigned char *outbuf, + int outbufSize, + int image_bytes, + int pixels_per_line, + int padded_bytes_per_scanline, + int reverse_bits, + int *bytesCompressed) + +{ + int bytes_per_scanline = ROUNDUP8 (pixels_per_line); + unsigned char *refline, *refptr; + unsigned char *save_inbuf = inbuf; + int bytes_left = image_bytes; + Buffer OutBuf; + int status, i; + + OutBuf.bufStart = OutBuf.bufPtr = outbuf; + OutBuf.bufSize = OutBuf.bytesLeft = outbufSize; + + if (!(refline = (unsigned char *) malloc (bytes_per_scanline + 1))) + return (LBX_IMAGE_COMPRESS_BAD_MALLOC); + + refptr = refline + 1; + + for (i = 0; i < bytes_per_scanline + 1; i++) + refline[i] = 0xff; + + if (reverse_bits) + LbxReverseBits (inbuf, image_bytes); + + sp_bit = 8; + sp_data = 0; + + while (bytes_left > 0) + { + if (!(status = EncodeFaxG42D (inbuf, refptr, + pixels_per_line, &OutBuf))) + { + goto bad; + } + + memcpy (refptr, inbuf, bytes_per_scanline); + + inbuf += padded_bytes_per_scanline; + bytes_left -= padded_bytes_per_scanline; + } + + status = putbits (EOL, 12, &OutBuf); + if (status) + status = putbits (EOL, 12, &OutBuf); + if (status && sp_bit != 8) + { + status = flushbits (&OutBuf); + } + + bad: + + free ((char *) refline); + + /* put the bits back the way they were */ + if (reverse_bits) + LbxReverseBits (save_inbuf, image_bytes); + + if (status) + { + *bytesCompressed = OutBuf.bufPtr - OutBuf.bufStart; + + if (OutBuf.bytesLeft > 0) + return (LBX_IMAGE_COMPRESS_SUCCESS); + else + return (LBX_IMAGE_COMPRESS_NOT_WORTH_IT); + } + else + return (LBX_IMAGE_COMPRESS_NOT_WORTH_IT); +} |