faxexpand.c
来自「涉及Fax/Mail/Voice通讯编程的一个程序」· C语言 代码 · 共 730 行 · 第 1/2 页
C
730 行
expand1d(); if (RunLength) SETVAL(0); if (a0 != lastx) { if (verbose) fprintf(stderr, "Line %d: length is %d (expected %d)\n", LineNum, a0, lastx); while (a0 > lastx) a0 -= *--pa; if (a0 < lastx) { if ((pa - runs) & 1) SETVAL(0); SETVAL(lastx - a0); } } (*df)(runs, LineNum++, pn); } free(runs);}/* Expand group-3 1-dimensional data */voidg31expand(struct pagenode *pn, drawfunc df){ int a0; /* reference element */ int lastx = pn->width; /* copy line width to register */ t32bits BitAcc; /* bit accumulator */ int BitsAvail; /* # valid bits in BitAcc */ int RunLength; /* Length of current run */ t16bits *sp; /* pointer into compressed data */ pixnum *pa; /* pointer into new line */ int EOLcnt; /* number of consecutive EOLs */ int LineNum; /* line number */ pixnum *runs; /* list of run lengths */ struct tabent *TabEnt; sp = pn->data; BitAcc = 0; BitsAvail = 0; lastx = pn->width; runs = (pixnum *) xmalloc(lastx * sizeof(pixnum)); EOLcnt = 0; for (LineNum = 0; LineNum < pn->rowsperstrip; ) {#ifdef DEBUG printf("\nBitAcc=%08lX, BitsAvail = %d\n", BitAcc, BitsAvail); printf("-------------------- %d\n", LineNum); fflush(stdout);#endif if (EOLcnt == 0) while (!EndOfData(pn)) { /* skip over garbage after a coding error */ NeedBits(11); if (GetBits(11) == 0) break; ClrBits(1); } for (EOLcnt = 1; !EndOfData(pn); EOLcnt++) { /* we have seen 11 zeros, which implies EOL, skip possible fill bits too */ while (1) { NeedBits(8); if (GetBits(8)) break; ClrBits(8); } while (GetBits(1) == 0) ClrBits(1); ClrBits(1); /* the eol flag */ NeedBits(11); if (GetBits(11)) break; ClrBits(11); } if (EOLcnt > 1 && EOLcnt != 6 && verbose) fprintf(stderr, "Line %d: bad RTC (%d EOLs)\n", LineNum, EOLcnt); if (EOLcnt >= 6 || EndOfData(pn)) { free(runs); return; } RunLength = 0; pa = runs; a0 = 0; EOLcnt = 0; expand1d(); if (RunLength) SETVAL(0); if (a0 != lastx) { if (verbose) fprintf(stderr, "Line %d: length is %d (expected %d)\n", LineNum, a0, lastx); while (a0 > lastx) a0 -= *--pa; if (a0 < lastx) { if ((pa - runs) & 1) SETVAL(0); SETVAL(lastx - a0); } } (*df)(runs, LineNum++, pn); } free(runs);}/* Expand group-3 2-dimensional data */voidg32expand(struct pagenode *pn, drawfunc df){ int RunLength; /* Length of current run */ int a0; /* reference element */ int b1; /* next change on previous line */ int lastx = pn->width; /* copy line width to register */ pixnum *run0, *run1; /* run length arrays */ pixnum *thisrun, *pa, *pb; /* pointers into runs */ t16bits *sp; /* pointer into compressed data */ t32bits BitAcc; /* bit accumulator */ int BitsAvail; /* # valid bits in BitAcc */ int EOLcnt; /* number of consecutive EOLs */ int refline = 0; /* 1D encoded reference line */ int LineNum; /* line number */ struct tabent *TabEnt; sp = pn->data; BitAcc = 0; BitsAvail = 0; /* allocate space for 2 runlength arrays */ run0 = (pixnum *) xmalloc(2 * ((lastx+5)&~1) * sizeof(pixnum)); run1 = run0 + ((lastx+5)&~1); run1[0] = lastx; run1[1] = 0; EOLcnt = 0; for (LineNum = 0; LineNum < pn->rowsperstrip; ) {#ifdef DEBUG printf("\nBitAcc=%08lX, BitsAvail = %d\n", BitAcc, BitsAvail); printf("-------------------- %d\n", LineNum); fflush(stdout);#endif if (EOLcnt == 0) while (!EndOfData(pn)) { /* skip over garbage after a coding error */ NeedBits(11); if (GetBits(11) == 0) break; ClrBits(1); } for (EOLcnt = 1; !EndOfData(pn); EOLcnt++) { /* we have seen 11 zeros, which implies EOL, skip possible fill bits too */ while (1) { NeedBits(8); if (GetBits(8)) break; ClrBits(8); } while (GetBits(1) == 0) ClrBits(1); ClrBits(1); /* the eol flag */ NeedBits(12); refline = GetBits(1); /* 1D / 2D flag */ ClrBits(1); if (GetBits(11)) break; ClrBits(11); } if (EOLcnt > 1 && EOLcnt != 6 && verbose) fprintf(stderr, "Line %d: bad RTC (%d EOLs)\n", LineNum, EOLcnt); if (EOLcnt >= 6 || EndOfData(pn)) { free(run0); return; } if (LineNum == 0 && refline == 0 && verbose) fprintf(stderr, "First line is 2-D encoded\n"); RunLength = 0; if (LineNum & 1) { pa = run1; pb = run0; } else { pa = run0; pb = run1; } thisrun = pa; EOLcnt = 0; a0 = 0; b1 = *pb++; if (refline) { expand1d(); } else { expand2d(EOL2); } if (RunLength) SETVAL(0); if (a0 != lastx) { if (verbose) fprintf(stderr, "Line %d: length is %d (expected %d)\n", LineNum, a0, lastx); while (a0 > lastx) a0 -= *--pa; if (a0 < lastx) { if ((pa - run0) & 1) SETVAL(0); SETVAL(lastx - a0); } } SETVAL(0); /* imaginary change at end of line for reference */ (*df)(thisrun, LineNum++, pn); } free(run0);}/* Redefine the "skip to eol" macro. We cannot recover from coding errors in G4 data */#undef SKIP_EOL#undef eol2lab#define SKIP_EOL do { \ if (verbose) \ fprintf(stderr, "Line %d: G4 coding error\n", LineNum); \ free(run0); \ return; \} while (0)#define eol2lab/* Expand group-4 data */voidg4expand(struct pagenode *pn, drawfunc df){ int RunLength; /* Length of current run */ int a0; /* reference element */ int b1; /* next change on previous line */ int lastx = pn->width; /* copy line width to register */ pixnum *run0, *run1; /* run length arrays */ pixnum *thisrun, *pa, *pb; /* pointers into runs */ t16bits *sp; /* pointer into compressed data */ t32bits BitAcc; /* bit accumulator */ int BitsAvail; /* # valid bits in BitAcc */ int LineNum; /* line number */ int EOLcnt; struct tabent *TabEnt; sp = pn->data; BitAcc = 0; BitsAvail = 0; /* allocate space for 2 runlength arrays */ run0 = (pixnum *) xmalloc(2 * ((lastx+5)&~1) * sizeof(pixnum)); run1 = run0 + ((lastx+5)&~1); run1[0] = lastx; /* initial reference line */ run1[1] = 0; for (LineNum = 0; LineNum < pn->rowsperstrip; ) {#ifdef DEBUG printf("\nBitAcc=%08lX, BitsAvail = %d\n", BitAcc, BitsAvail); printf("-------------------- %d\n", LineNum); fflush(stdout);#endif RunLength = 0; if (LineNum & 1) { pa = run1; pb = run0; } else { pa = run0; pb = run1; } thisrun = pa; a0 = 0; b1 = *pb++; expand2d(EOFB); if (a0 < lastx) { if ((pa - run0) & 1) SETVAL(0); SETVAL(lastx - a0); } SETVAL(0); /* imaginary change at end of line for reference */ (*df)(thisrun, LineNum++, pn); continue; EOFB: NeedBits(13); if (GetBits(13) != 0x1001 && verbose) fputs("Bad RTC\n", stderr); break; } free(run0);}static unsigned char zerotab[256] = { 0x88, 0x07, 0x16, 0x06, 0x25, 0x05, 0x15, 0x05, 0x34, 0x04, 0x14, 0x04, 0x24, 0x04, 0x14, 0x04, 0x43, 0x03, 0x13, 0x03, 0x23, 0x03, 0x13, 0x03, 0x33, 0x03, 0x13, 0x03, 0x23, 0x03, 0x13, 0x03, 0x52, 0x02, 0x12, 0x02, 0x22, 0x02, 0x12, 0x02, 0x32, 0x02, 0x12, 0x02, 0x22, 0x02, 0x12, 0x02, 0x42, 0x02, 0x12, 0x02, 0x22, 0x02, 0x12, 0x02, 0x32, 0x02, 0x12, 0x02, 0x22, 0x02, 0x12, 0x02, 0x61, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x31, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x41, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x31, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x51, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x31, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x41, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x31, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x70, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x50, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x60, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x50, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00};#define check(v) do { \ prezeros = zerotab[v]; \ postzeros = prezeros & 15; \ prezeros >>= 4; \ if (prezeros == 8) { \ zeros += 8; \ continue; \ } \ if (zeros + prezeros < 11) { \ empty = 0; \ zeros = postzeros; \ continue; \ } \ zeros = postzeros; \ if (empty) \ EOLcnt++; \ lines++; \ empty = 1; \} while (0)/* count fax lines */intG3count(struct pagenode *pn, int twoD){ t16bits *p = pn->data; t16bits *end = p + pn->length/sizeof(*p); int lines = 0; /* lines seen so far */ int zeros = 0; /* number of consecutive zero bits seen */ int EOLcnt = 0; /* number of consecutive EOLs seen */ int empty = 1; /* empty line */ int prezeros, postzeros; while (p < end && EOLcnt < 6) { t16bits bits = *p++; check(bits&255); if (twoD && (prezeros + postzeros == 7)) { if (postzeros || ((bits & 0x100) == 0)) zeros--; } check(bits>>8); if (twoD && (prezeros + postzeros == 7)) { if (postzeros || ((p < end) && ((*p & 1) == 0))) zeros--; } } return lines - EOLcnt; /* don't count trailing EOLs */}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?