home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.infoflex.se
/
2015-02-10.ftp.infoflex.se.tar
/
ftp.infoflex.se
/
pub
/
xfax
/
ghostscript
/
gdevxfax.c
next >
Wrap
C/C++ Source or Header
|
2004-07-22
|
35KB
|
1,359 lines
/*
* gdevxfax.c
* By Nordic Messaging Tech. AB, Sweden, 2001-2002.
* Hopefully you find this XFAX driver for Ghostscript
* useful. However, with provide it WITHOUT ANY
* WARRANTY. You use it at YOUR OWN RISK.
* Visit us at http://www.nordicmessaging.se or send
* e-mail at info@nordicmessaging.se.
*
* We are helpful but do NOT guarantee support for
* this Ghostscript driver.
*
* Jan 20, 2004, version 1.2, be sure lines end with blank space
* Oct 23, 2002, version 1.1, added support for appending
* when output file already exists.
*/
#include "gdevprn.h"
#include "std.h"
#include <sys/stat.h>
#include "gdevxfax.h"
unsigned char huffman_white[130] = {
8, /* ;0 */
6, /* ;1 */
4, /* ;2 */
4, /* ;3 */
4, /* ;4 */
4, /* ;5 */
4, /* ;6 */
4, /* ;7 */
5, /* ;8 */
5, /* ;9 */
5, /* ;10 */
5, /* ;11 */
6, /* ;12 */
6, /* ;13 */
6, /* ;14 */
6, /* ;15 */
6, /* ;16 */
6, /* ;17 */
7, /* ;18 */
7, /* ;19 */
7, /* ;20 */
7, /* ;21 */
7, /* ;22 */
7, /* ;23 */
7, /* ;24 */
7, /* ;25 */
7, /* ;26 */
7, /* ;27 */
7, /* ;28 */
8, /* ;29 */
8, /* ;30 */
8, /* ;31 */
8, /* ;32 */
8, /* ;33 */
8, /* ;34 */
8, /* ;35 */
8, /* ;36 */
8, /* ;37 */
8, /* ;38 */
8, /* ;39 */
8, /* ;40 */
8, /* ;41 */
8, /* ;42 */
8, /* ;43 */
8, /* ;44 */
8, /* ;45 */
8, /* ;46 */
8, /* ;47 */
8, /* ;48 */
8, /* ;49 */
8, /* ;50 */
8, /* ;51 */
8, /* ;52 */
8, /* ;53 */
8, /* ;54 */
8, /* ;55 */
8, /* ;56 */
8, /* ;57 */
8, /* ;58 */
8, /* ;59 */
8, /* ;60 */
8, /* ;61 */
8, /* ;62 */
8, /* ;63 */
/*
; White make-up code lengths:
*/
5, /* ;64 */
5, /* ;128 */
6, /* ;192 */
7, /* ;256 */
8, /* ;320 */
8, /* ;384 */
8, /* ;448 */
8, /* ;512 */
8, /* ;576 */
8, /* ;640 */
9, /* ;704 */
9, /* ;768 */
9, /* ;832 */
9, /* ;896 */
9, /* ;960 */
9, /* ;1024 */
9, /* ;1088 */
9, /* ;1152 */
9, /* ;1216 */
9, /* ;1280 */
9, /* ;1344 */
9, /* ;1408 */
9, /* ;1472 */
9, /* ;1536 */
9, /* ;1600 */
6, /* ;1664 */
9, /* ;1728 */
11, /* ;1792 */
11, /* ;1856 */
11, /* ;1920 */
12, /* ;1984 */
12, /* ;2048 */
12, /* ;2112 */
12, /* ;2176 */
12, /* ;2240 */
12, /* ;2304 */
12, /* ;2368 */
12, /* ;2432 */
12, /* ;2496 */
12 /* ;2560 */
};
/*
; White data:
*/
unsigned short int huffman1[] = {
0x3500, /* B ;0 */
0x1c00, /* B ;1 */
0x7000, /* B ;2 */
0x8000, /* B ;3 */
0xb000, /* B ;4 */
0xc000, /* B ;5 */
0xe000, /* B ;6 */
0xf000, /* B ;7 */
0x9800, /* B ;8 */
0xa000, /* B ;9 */
0x3800, /* B ;10 */
0x4000, /* B ;11 */
0x2000, /* B ;12 */
0x0c00, /* B ;13 */
0xd000, /* B ;14 */
0xd400, /* B ;15 */
0xa800, /* B ;16 */
0xac00, /* B ;17 */
0x4e00, /* B ;18 */
0x1800, /* B ;19 */
0x1000, /* B ;20 */
0x2e00, /* B ;21 */
0x0600, /* B ;22 */
0x0800, /* B ;23 */
0x5000, /* B ;24 */
0x5600, /* B ;25 */
0x2600, /* B ;26 */
0x4800, /* B ;27 */
0x3000, /* B ;28 */
0x0200, /* B ;29 */
0x0300, /* B ;30 */
0x1a00, /* B ;31 */
0x1b00, /* B ;32 */
0x1200, /* B ;33 */
0x1300, /* B ;34 */
0x1400, /* B ;35 */
0x1500, /* B ;36 */
0x1600, /* B ;37 */
0x1700, /* B ;38 */
0x2800, /* B ;39 */
0x2900, /* B ;40 */
0x2a00, /* B ;41 */
0x2b00, /* B ;42 */
0x2c00, /* B ;43 */
0x2d00, /* B ;44 */
0x0400, /* B ;45 */
0x0500, /* B ;46 */
0x0a00, /* B ;47 */
0x0b00, /* B ;48 */
0x5200, /* B ;49 */
0x5300, /* B ;50 */
0x5400, /* B ;51 */
0x5500, /* B ;52 */
0x2400, /* B ;53 */
0x2500, /* B ;54 */
0x5800, /* B ;55 */
0x5900, /* B ;56 */
0x5a00, /* B ;57 */
0x5b00, /* B ;58 */
0x4a00, /* B ;59 */
0x4b00, /* B ;60 */
0x3200, /* B ;61 */
0x3300, /* B ;62 */
0x3400, /* B ;63 */
/*
; White make-up data:
*/
0xd800, /* B ;64 */
0x9000, /* B ;128 */
0x5c00, /* B ;192 */
0x6e00, /* B ;256 */
0x3600, /* B ;320 */
0x3700, /* B ;384 */
0x6400, /* B ;448 */
0x6500, /* B ;512 */
0x6800, /* B ;576 */
0x6700, /* B ;640 */
0x6600, /* B ;704 */
0x6680, /* B ;768 */
0x6900, /* B ;832 */
0x6980, /* B ;896 */
0x6a00, /* B ;960 */
0x6a80, /* B ;1024 */
0x6b00, /* B ;1088 */
0x6b80, /* B ;1152 */
0x6c00, /* B ;1216 */
0x6c80, /* B ;1280 */
0x6d00, /* B ;1344 */
0x6d80, /* B ;1408 */
0x4c00, /* B ;1472 */
0x4c80, /* B ;1536 */
0x4d00, /* B ;1600 */
0x6000, /* B ;1664 */
0x4d80, /* B ;1728 */
0x0100, /* B ;1792 */
0x0180, /* B ;1856 */
0x01a0, /* B ;1920 */
0x0120, /* B ;1984 */
0x0130, /* B ;2048 */
0x0140, /* B ;2112 */
0x0150, /* B ;2176 */
0x0160, /* B ;2240 */
0x0170, /* B ;2304 */
0x01c0, /* B ;2368 */
0x01d0, /* B ;2432 */
0x01e0, /* B ;2496 */
0x01f0 /* B ;2560 */
};
unsigned char huffman_black[] = {
10, /* ;0 */
3, /* ;1 */
2, /* ;2 */
2, /* ;3 */
3, /* ;4 */
4, /* ;5 */
4, /* ;6 */
5, /* ;7 */
6, /* ;8 */
6, /* ;9 */
7, /* ;10 */
7, /* ;11 */
7, /* ;12 */
8, /* ;13 */
8, /* ;14 */
9, /* ;15 */
10, /* ;16 */
10, /* ;17 */
10, /* ;18 */
11, /* ;19 */
11, /* ;20 */
11, /* ;21 */
11, /* ;22 */
11, /* ;23 */
11, /* ;24 */
11, /* ;25 */
12, /* ;26 */
12, /* ;27 */
12, /* ;28 */
12, /* ;29 */
12, /* ;30 */
12, /* ;31 */
12, /* ;32 */
12, /* ;33 */
12, /* ;34 */
12, /* ;35 */
12, /* ;36 */
12, /* ;37 */
12, /* ;38 */
12, /* ;39 */
12, /* ;40 */
12, /* ;41 */
12, /* ;42 */
12, /* ;43 */
12, /* ;44 */
12, /* ;45 */
12, /* ;46 */
12, /* ;47 */
12, /* ;48 */
12, /* ;49 */
12, /* ;50 */
12, /* ;51 */
12, /* ;52 */
12, /* ;53 */
12, /* ;54 */
12, /* ;55 */
12, /* ;56 */
12, /* ;57 */
12, /* ;58 */
12, /* ;59 */
12, /* ;60 */
12, /* ;61 */
12, /* ;62 */
12, /* ;63 */
/*
; Black make-up code lengths:
*/
10, /* ;64 */
12, /* ;128 */
12, /* ;192 */
12, /* ;256 */
12, /* ;320 */
12, /* ;384 */
12, /* ;448 */
13, /* ;512 */
13, /* ;576 */
13, /* ;640 */
13, /* ;704 */
13, /* ;768 */
13, /* ;832 */
13, /* ;896 */
13, /* ;960 */
13, /* ;1024 */
13, /* ;1088 */
13, /* ;1152 */
13, /* ;1216 */
13, /* ;1280 */
13, /* ;1344 */
13, /* ;1408 */
13, /* ;1472 */
13, /* ;1536 */
13, /* ;1600 */
13, /* ;1664 */
13, /* ;1728 */
11, /* ;1792 */
11, /* ;1856 */
11, /* ;1920 */
12, /* ;1984 */
12, /* ;2048 */
12, /* ;2112 */
12, /* ;2176 */
12, /* ;2240 */
12, /* ;2304 */
12, /* ;2368 */
12, /* ;2432 */
12, /* ;2496 */
12 /* ;2560 */
};
/*
; Black data:
*/
unsigned short int huffman2[] = {
0x0dc0, /* ;0 */
0x4000, /* ;1 */
0xc000, /* ;2 */
0x8000, /* ;3 */
0x6000, /* ;4 */
0x3000, /* ;5 */
0x2000, /* ;6 */
0x1800, /* ;7 */
0x1400, /* ;8 */
0x1000, /* ;9 */
0x0800, /* ;10 */
0x0a00, /* ;11 */
0x0e00, /* ;12 */
0x0400, /* ;13 */
0x0700, /* ;14 */
0x0c00, /* ;15 */
0x05c0, /* ;16 */
0x0600, /* ;17 */
0x0200, /* ;18 */
0x0ce0, /* ;19 */
0x0d00, /* ;20 */
0x0d80, /* ;21 */
0x06e0, /* ;22 */
0x0500, /* ;23 */
0x02e0, /* ;24 */
0x0300, /* ;25 */
0x0ca0, /* ;26 */
0x0cb0, /* ;27 */
0x0cc0, /* ;28 */
0x0cd0, /* ;29 */
0x0680, /* ;30 */
0x0690, /* ;31 */
0x06a0, /* ;32 */
0x06b0, /* ;33 */
0x0d20, /* ;34 */
0x0d30, /* ;35 */
0x0d40, /* ;36 */
0x0d50, /* ;37 */
0x0d60, /* ;38 */
0x0d70, /* ;39 */
0x06c0, /* ;40 */
0x06d0, /* ;41 */
0x0da0, /* ;42 */
0x0db0, /* ;43 */
0x0540, /* ;44 */
0x0550, /* ;45 */
0x0560, /* ;46 */
0x0570, /* ;47 */
0x0640, /* ;48 */
0x0650, /* ;49 */
0x0520, /* ;50 */
0x0530, /* ;51 */
0x0240, /* ;52 */
0x0370, /* ;53 */
0x0380, /* ;54 */
0x0270, /* ;55 */
0x0280, /* ;56 */
0x0580, /* ;57 */
0x0590, /* ;58 */
0x02b0, /* ;59 */
0x02c0, /* ;60 */
0x05a0, /* ;61 */
0x0660, /* ;62 */
0x0670, /* ;63 */
/*
; Black make-up data:
*/
0x03c0, /* ;64 */
0x0c80, /* ;128 */
0x0c90, /* ;192 */
0x05b0, /* ;256 */
0x0330, /* ;320 */
0x0340, /* ;384 */
0x0350, /* ;448 */
0x0360, /* ;512 */
0x0368, /* ;576 */
0x0250, /* ;640 */
0x0258, /* ;704 */
0x0260, /* ;768 */
0x0268, /* ;832 */
0x0390, /* ;896 */
0x0398, /* ;960 */
0x03a0, /* ;1024 */
0x03a8, /* ;1088 */
0x03b0, /* ;1152 */
0x03b8, /* ;1216 */
0x0290, /* ;1280 */
0x0298, /* ;1344 */
0x02a0, /* ;1408 */
0x02a8, /* ;1472 */
0x02d0, /* ;1536 */
0x02d8, /* ;1600 */
0x0320, /* ;1664 */
0x0328, /* ;1728 */
0x0100, /* ;1792 */
0x0180, /* ;1856 */
0x01a0, /* ;1920 */
0x0120, /* ;1984 */
0x0130, /* ;2048 */
0x0140, /* ;2112 */
0x0150, /* ;2176 */
0x0160, /* ;2240 */
0x0170, /* ;2304 */
0x01c0, /* ;2368 */
0x01d0, /* ;2432 */
0x01e0, /* ;2496 */
0x01f0 /* ;2560 */
};
unsigned char rev_tab[] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
#ifdef __PROTOTYPES__
# define PROTO_ARGS(X) X
#else
# define PROTO_ARGS(X) ()
#endif
/*
* This appears before each page in a FAX file
*/
/**********************************************************************/
/*
* Generic fax output library
*/
/**********************************************************************/
static long curpos=-1;
private FAXOUT *faxout_open_fp PROTO_ARGS((FILE *));
private int faxout_begin_page PROTO_ARGS((FAXOUT *, int));
private int faxout_end_page PROTO_ARGS((FAXOUT *));
private void tofax(FAXOUT *, unsigned char *);
void xstart_line(FAXOUT *fax);
void xend_line(FAXOUT *fax);
/*************************************************************************
Redefine the device descriptor
*************************************************************************/
struct gx_device_xfax_s {
gx_device_common;
gx_prn_device_common;
FAXOUT *fax;
};
typedef struct gx_device_xfax_s gx_device_xfax;
/* The device descriptor */
#define X_DPI 204
#define Y_DPI 196
#define LINE_SIZE ((X_DPI * 85 / 10 + 7) / 8) /* bytes per line */
private dev_proc_open_device(xfax_prn_open);
private dev_proc_print_page(xfax_print_page);
private dev_proc_close_device(xfax_prn_close);
gx_device_procs xfax_std_procs =
prn_procs(xfax_prn_open, gdev_prn_output_page, xfax_prn_close);
gx_device_xfax gs_xfaxhigh_device =
{ prn_device_std_body(
gx_device_xfax,
xfax_std_procs,
"xfaxhigh",
85, /* width_10ths, 8.5" */
110, /* height_10ths, 11" */
X_DPI, Y_DPI,
0,0,0,0, /* margins */
1,
xfax_print_page
)
};
gx_device_xfax gs_xfaxlow_device =
{ prn_device_std_body(
gx_device_xfax,
xfax_std_procs,
"xfaxlow",
85, /* width_10ths, 8.5" */
110, /* height_10ths, 11" */
X_DPI, Y_DPI/2,
0,0,0,0, /* margins */
1,
xfax_print_page
)
};
/*************************************************************************
Driver entry points
*************************************************************************/
private int
xfax_prn_open(gx_device *pdev)
{
gx_device_xfax *ddev = (gx_device_xfax *) pdev;
gx_device_printer *ppdev = (gx_device_printer *) pdev;
int rc;
rc = gdev_prn_open(pdev);
if((ddev->file=fopen(ppdev->fname, "rb+"))==NULL)
ddev->file=fopen(ppdev->fname, "wb+");
ddev->fax = faxout_open_fp(ddev->file);
return (rc);
}
private int
xfax_print_page(gx_device_printer *pdev, FILE *prn_stream)
{
gx_device_xfax *ddev = (gx_device_xfax *) pdev;
char data[LINE_SIZE + 4];
int lnum;
int line_size;
FAXOUT *fax = ddev->fax;
/* For some odd reason, the file isn't open until now */
fax->fp = prn_stream;
faxout_begin_page(fax, ddev->y_pixels_per_inch > 120);
line_size = gdev_mem_bytes_per_scan_line( (gx_device *) pdev);
for ( lnum = 0; lnum < pdev->height; lnum++ )
{
memset(data, 0, LINE_SIZE + 4);
gdev_prn_copy_scan_lines(pdev, lnum, (byte *)data, line_size);
tofax(fax, data);
}
/* Make sure each page is 2238 scanlines */
memset(data, 0, LINE_SIZE + 4);
for ( ; lnum < 2238; lnum++ ) {
tofax(fax, data);
}
faxout_end_page(fax);
return 0;
}
private int
xfax_prn_close(gx_device *pdev)
{
return(gdev_prn_close(pdev));
}
/*************************************************************************
Internal routines
*************************************************************************/
/************************Coding FAX Routines*************************/
/*
* faxp = faxout_open_fp(fp);
* faxout_begin_page(faxp, resolution);
* for(;;) tofax(faxp, linebuf);
* faxout_end_page(faxp);
*/
long
read_header(FILE *fp)
{
int i;
char header[16];
long offset=0;
if(fp==NULL) return -1;
if(fread(header, sizeof(header), 1, fp)!=sizeof(header)) {
fseek(fp, 0L, SEEK_SET);
return -1;
}
for(i=7;i>=4;i--) {
offset=offset<<8;
offset+=header[i];
}
return(offset);
}
private FAXOUT *
faxout_open_fp(FILE *fp)
{
long startpos;
register FAXOUT *faxp;
faxp = (FAXOUT *) malloc(sizeof(*faxp));
faxp->fp = fp;
faxp->fax_byte = 0;
faxp->fax_weight = 0x80;
faxp->pages = 0;
if((startpos=read_header(fp))>=0) {
fseek(faxp->fp, startpos, SEEK_SET);
}
return (faxp);
}
private int
faxout_begin_page(FAXOUT *faxp, int resolution)
{
char header[16];
if(curpos==-1) {
fseek(faxp->fp, 0L, SEEK_END);
}
memset(header, 0, sizeof(header));
header[0]=0x10; header[1]=0x10; header[2]=0x10;
/* High resolution */
header[3]=0x01;
header[4]=0; header[5]=0; header[6]=0; header[7]=0;
header[8]='X'; header[9]='F'; header[10]='A'; header[11]='X';
curpos=ftell(faxp->fp);
fwrite((char*)header, 1, 16, faxp->fp);
fflush(faxp->fp);
return (0);
}
private int
faxout_end_page(FAXOUT *faxp)
{
char header[16];
int i, n;
long pos;
long offset;
pos=ftell(faxp->fp);
offset=pos;
memset(header, 0, sizeof(header));
header[0]=0x10; header[1]=0x10; header[2]=0x10;
/* High resolution */
header[3]=0x01;
header[4]=0; header[5]=0; header[6]=0; header[7]=0;
header[8]='X'; header[9]='F'; header[10]='A'; header[11]='X';
for(i=4;i<=7;i++) {
header[i]=offset&0xff;
offset>>=8;
}
fseek(faxp->fp, curpos, SEEK_SET);
fwrite((char *)header, 1, 16, faxp->fp);
fseek(faxp->fp, pos, SEEK_SET);
return (0);
}
private unsigned char b_run_tbl[8][256] =
{
{ /* START BIT 0 */
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
},
{ /* START BIT 1 */
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
},
{ /* START BIT 2 */
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
0, 0, 0, 0, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 2, 3,
},
{ /* START BIT 3 */
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4,
},
{ /* START BIT 4 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5,
},
{ /* START BIT 5 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6,
},
{ /* START BIT 6 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7,
},
{ /* START BIT 7 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,
},
};
private unsigned char w_run_tbl[8][256] =
{
{ /* START BIT 0 */
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
},
{ /* START BIT 1 */
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
},
{ /* START BIT 2 */
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
3, 2, 1, 1, 0, 0, 0, 0, 3, 2, 1, 1, 0, 0, 0, 0,
},
{ /* START BIT 3 */
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
},
{ /* START BIT 4 */
5, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
},
{ /* START BIT 5 */
6, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
},
{ /* START BIT 6 */
7, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
},
{ /* START BIT 7 */
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
},
};
/*
* Macros to use tables in findrun.c
* Input is *p, bit
* Output is rl, *p, bit
*/
#define find_black_run() \
for (rl = 0;;) \
{ \
if (run = b_run_tbl[bit][*p]) \
{ \
rl += run; \
bit -= run; \
if (bit < 0 && ++p < ep) { bit=7; continue;} \
} \
break; \
}
#define find_white_run() \
for (rl = 0;;) \
{ \
if (run = w_run_tbl[bit][*p]) \
{ \
rl += run; \
bit -= run; \
if (bit < 0 && ++p < ep) { bit=7; continue;} \
} \
break; \
}
extern void store_run(unsigned int length);
private void
tofax(FAXOUT *faxp, unsigned char *p)
{
unsigned char *ep;
register int bit;
register int run;
register int rl;
ep = p + FAX_WIDTH/8;
bit = 7;
xstart_line(faxp);
for (;;)
{
find_white_run();
store_run(rl);
if (p >= ep) break;
find_black_run();
store_run(rl);
if (p >= ep) break;
}
xend_line(faxp);
}
#define MH_BUFFER_SIZE 0x800
#define out_buffer_size 0x400
#define MAKE_UP_OFFSET 64
#define RUN_DATA_OFFSET 104
#define MAKE_UP_DATA_OFFSET 232
/*
; External variables
;-------------------
*/
char wbuf[2048];
int inx=0;
extern PAGE *Page;
extern UCHAR huffman_black[];
extern USHORT huffman1[];
extern UCHAR huffman_white[];
extern USHORT huffman2[];
extern UCHAR rev_tab[];
UCHAR *huffman_table; /* DW ? ;Pointer to table in use */
unsigned short int *huffman_codes;
UCHAR huffman_color = 0; /* DB 0 ;White at start of line */
UCHAR shifts = 0; /* DB 0 */
UCHAR mh_left_over = 0; /* DB 0 */
UCHAR *mh_buff_ptr; /* DW ? ;Pointer to buffer */
unsigned int xpos = 0; /* DW 0 ;X offset along line */
int in_line = 0; /* DW 0 ;Set when doing line */
unsigned int filekbytes = 0; /* DW 0 ;Size of the file in Kbytes */
unsigned int filebytes = 0; /* DW 0 ;plus the remainder */
int line_bits = 0; /* DW 0 ;Number of bits in the MH */
UCHAR *mh_buffer=NULL; /* DUP (?) ;Buffer for MH */
UCHAR out_buffer[out_buffer_size]; /* DUP (?) ;Fax file output buffer */
UCHAR *out_buffer_ptr = 0; /* DW 0 ;Pointer to output buffer */
/*
;-----------------------------------------------------------------------------
; store_run (length) - Store run as MH
;-----------------------------------------------------------------------------
*/
#if arch_is_big_endian
struct _gnu { UCHAR h; UCHAR l; };
#else
struct _gnu { UCHAR l; UCHAR h; };
#endif
union aq1 {
unsigned short x;
struct _gnu oo;
} aq1, aq2, aq3;
#define ax aq1.x
#define ah aq1.oo.h
#define al aq1.oo.l
#define cx aq2.x
#define ch aq2.oo.h
#define cl aq2.oo.l
#define bx aq3.x
#define bh aq3.oo.h
#define bl aq3.oo.l
static UCHAR *di, *si;
static unsigned int dx;
/*
;-----------------------------------------------------------------------------
; DO_STORE_RUN
;
; Stores the next MH code (in DX) in the line buffer pointed to by DI. The
; number of bits in the code are given in AL and the number of shifts
; required to align the code are given in CL.
;-----------------------------------------------------------------------------
*/
void
do_store_run()
{
line_bits += al;
bh=(dx&255);
dx >>= cl;
dx |= (mh_left_over << 8);
/*
; (AH will hold the next incomplete byte to be incorporated).
*/
ah = (dx >> 8) & 255;
al += cl;
if (al > 7) {
ah = dx & 255;
*di++ = (dx >> 8) & 255;
if (al > 15) {
/* ???? */
bx=bx&(0xff00);
bx>>=cl;
/* ???? */
ah = bx & 255;
*di++ = dx & 255;
}
}
mh_left_over = ah;
cl = al & 7;
}
/* * * * * * * * * * * * * * * * * * * * * * * * *
STORE_RUN
* * * * * * * * * * * * * * * * * * * * * * * * */
void
store_run(unsigned int length)
{
register unsigned bx2;
di = mh_buff_ptr;
si = huffman_table;
bx = length;
/*
; We check that this run does not go beyond the right edge of the paper -
; fax_page_width contains the number of pixels across the page. If it
; does, we clip this run to the width of the page.
*/
if (FAX_WIDTH<= xpos) return;
ax = bx + xpos;
if (ax >= FAX_WIDTH) {
ax = FAX_WIDTH - xpos;
bx = ax;
}
cl = shifts;
xpos += bx;
if (bx > 63) {
bx2 = bx;
bx >>= 6;
bx--;
al = huffman_table[bx + MAKE_UP_OFFSET];
dx = huffman_codes[bx + MAKE_UP_OFFSET];
do_store_run();
bx = bx2 & 0x3f;
}
al = huffman_table[bx];
dx = huffman_codes[bx];
do_store_run();
shifts = cl;
/*
; (Finally, we change colour in prepartion for the next run length we're
; given).
*/
huffman_color = ~huffman_color;
if (huffman_color) {
si = huffman_black;
huffman_codes = huffman2;
} else {
si = huffman_white;
huffman_codes = huffman1;
}
huffman_table = si;
mh_buff_ptr = di;
}
/*
;-----------------------------------------------------------------------------
; start_line () - Start a new line of MH
;-----------------------------------------------------------------------------
*/
void
xstart_line(FAXOUT *fax)
{
if(mh_buffer==NULL) {
mh_buffer=malloc(MH_BUFFER_SIZE+10);
mh_buffer+=2;
}
huffman_table = huffman_white;
huffman_codes = huffman1;
mh_buff_ptr = mh_buffer;
mh_left_over = 0;
huffman_color = 0;
shifts = 0;
line_bits = 0;
xpos = 0;
in_line = ~0;
}
/*
;-----------------------------------------------------------------------------
; end_line () - Ends line of MH
;
; At the end of the a line of MH, any incomplete bytes must be written to
; the output stream, each byte in the line reversed and the checksum
; calculated.
;-----------------------------------------------------------------------------
*/
void
xend_line(FAXOUT *fax)
{
UCHAR *dxp;
short int *shp, n;
if (!in_line) return;
di = mh_buff_ptr;
if (line_bits & 7)
*di++ = mh_left_over;
dxp = di;
di = mh_buffer;
cx = 0; cl = 0; ch = 0; bh = 0;
do {
*di = rev_tab[*di];
cl -= *di++;
} while (di < dxp);
shp = (short int *)(mh_buffer - 2);
dxp = mh_buffer - 2;
*dxp++ = 0x00;
*dxp++ = 0x80;
n=(int)(di-(UCHAR *)shp);
fwrite(shp, n, 1, fax->fp);
in_line = 0;
}