📄 tif_fax3.c
字号:
} bp += sp->b.rowbytes; cc -= sp->b.rowbytes; if (cc != 0) tif->tif_row++; } return (1);}static intFax3PostEncode(TIFF* tif){ Fax3EncodeState* sp = EncoderState(tif); if (sp->bit != 8) Fax3FlushBits(tif, sp); return (1);}static voidFax3Close(TIFF* tif){ if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) { Fax3EncodeState* sp = EncoderState(tif); u_int code = EOL; u_int length = 12; int i; if (is2DEncoding(sp)) code = (code<<1) | (sp->tag == G3_1D), length++; for (i = 0; i < 6; i++) Fax3PutBits(tif, code, length); Fax3FlushBits(tif, sp); }}static voidFax3Cleanup(TIFF* tif){ if (tif->tif_data) { if (Fax3State(tif)->rw_mode == O_RDONLY) { Fax3DecodeState* sp = DecoderState(tif); if (sp->runs) _TIFFfree(sp->runs); } else { Fax3EncodeState* sp = EncoderState(tif); if (sp->refline) _TIFFfree(sp->refline); } if (Fax3State(tif)->subaddress) _TIFFfree(Fax3State(tif)->subaddress); _TIFFfree(tif->tif_data); tif->tif_data = NULL; }}#define FIELD_BADFAXLINES (FIELD_CODEC+0)#define FIELD_CLEANFAXDATA (FIELD_CODEC+1)#define FIELD_BADFAXRUN (FIELD_CODEC+2)#define FIELD_RECVPARAMS (FIELD_CODEC+3)#define FIELD_SUBADDRESS (FIELD_CODEC+4)#define FIELD_RECVTIME (FIELD_CODEC+5)#define FIELD_OPTIONS (FIELD_CODEC+6)static const TIFFFieldInfo faxFieldInfo[] = { { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, FIELD_PSEUDO, FALSE, FALSE, "FaxMode" }, { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc" }, { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines" }, { TIFFTAG_BADFAXLINES, 1, 1, TIFF_SHORT, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines" }, { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData" }, { TIFFTAG_CONSECUTIVEBADFAXLINES,1,1, TIFF_LONG, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines" }, { TIFFTAG_CONSECUTIVEBADFAXLINES,1,1, TIFF_SHORT, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines" }, { TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, FIELD_RECVPARAMS, TRUE, FALSE, "FaxRecvParams" }, { TIFFTAG_FAXSUBADDRESS, -1,-1, TIFF_ASCII, FIELD_SUBADDRESS, TRUE, FALSE, "FaxSubAddress" }, { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, FIELD_RECVTIME, TRUE, FALSE, "FaxRecvTime" },};static const TIFFFieldInfo fax3FieldInfo[] = { { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, FIELD_OPTIONS, FALSE, FALSE, "Group3Options" },};static const TIFFFieldInfo fax4FieldInfo[] = { { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, FIELD_OPTIONS, FALSE, FALSE, "Group4Options" },};#define N(a) (sizeof (a) / sizeof (a[0]))static intFax3VSetField(TIFF* tif, ttag_t tag, va_list ap){ Fax3BaseState* sp = Fax3State(tif); switch (tag) { case TIFFTAG_FAXMODE: sp->mode = va_arg(ap, int); return (1); /* NB: pseudo tag */ case TIFFTAG_FAXFILLFUNC: if (sp->rw_mode == O_RDONLY) DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); return (1); /* NB: pseudo tag */ case TIFFTAG_GROUP3OPTIONS: case TIFFTAG_GROUP4OPTIONS: sp->groupoptions = va_arg(ap, uint32); break; case TIFFTAG_BADFAXLINES: sp->badfaxlines = va_arg(ap, uint32); break; case TIFFTAG_CLEANFAXDATA: sp->cleanfaxdata = (uint16) va_arg(ap, int); break; case TIFFTAG_CONSECUTIVEBADFAXLINES: sp->badfaxrun = va_arg(ap, uint32); break; case TIFFTAG_FAXRECVPARAMS: sp->recvparams = va_arg(ap, uint32); break; case TIFFTAG_FAXSUBADDRESS: _TIFFsetString(&sp->subaddress, va_arg(ap, char*)); break; case TIFFTAG_FAXRECVTIME: sp->recvtime = va_arg(ap, uint32); break; default: return (*sp->vsetparent)(tif, tag, ap); } TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); tif->tif_flags |= TIFF_DIRTYDIRECT; return (1);}static intFax3VGetField(TIFF* tif, ttag_t tag, va_list ap){ Fax3BaseState* sp = Fax3State(tif); switch (tag) { case TIFFTAG_FAXMODE: *va_arg(ap, int*) = sp->mode; break; case TIFFTAG_FAXFILLFUNC: if (sp->rw_mode == O_RDONLY) *va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill; break; case TIFFTAG_GROUP3OPTIONS: case TIFFTAG_GROUP4OPTIONS: *va_arg(ap, uint32*) = sp->groupoptions; break; case TIFFTAG_BADFAXLINES: *va_arg(ap, uint32*) = sp->badfaxlines; break; case TIFFTAG_CLEANFAXDATA: *va_arg(ap, uint16*) = sp->cleanfaxdata; break; case TIFFTAG_CONSECUTIVEBADFAXLINES: *va_arg(ap, uint32*) = sp->badfaxrun; break; case TIFFTAG_FAXRECVPARAMS: *va_arg(ap, uint32*) = sp->recvparams; break; case TIFFTAG_FAXSUBADDRESS: *va_arg(ap, char**) = sp->subaddress; break; case TIFFTAG_FAXRECVTIME: *va_arg(ap, uint32*) = sp->recvtime; break; default: return (*sp->vgetparent)(tif, tag, ap); } return (1);}static voidFax3PrintDir(TIFF* tif, FILE* fd, long flags){ Fax3BaseState* sp = Fax3State(tif); (void) flags; if (TIFFFieldSet(tif,FIELD_OPTIONS)) { const char* sep = " "; if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) { fprintf(fd, " Group 4 Options:"); if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED) fprintf(fd, "%suncompressed data", sep); } else { fprintf(fd, " Group 3 Options:"); if (sp->groupoptions & GROUP3OPT_2DENCODING) fprintf(fd, "%s2-d encoding", sep), sep = "+"; if (sp->groupoptions & GROUP3OPT_FILLBITS) fprintf(fd, "%sEOL padding", sep), sep = "+"; if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED) fprintf(fd, "%suncompressed data", sep); } fprintf(fd, " (%lu = 0x%lx)\n", (u_long) sp->groupoptions, (u_long) sp->groupoptions); } if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) { fprintf(fd, " Fax Data:"); switch (sp->cleanfaxdata) { case CLEANFAXDATA_CLEAN: fprintf(fd, " clean"); break; case CLEANFAXDATA_REGENERATED: fprintf(fd, " receiver regenerated"); break; case CLEANFAXDATA_UNCLEAN: fprintf(fd, " uncorrected errors"); break; } fprintf(fd, " (%u = 0x%x)\n", sp->cleanfaxdata, sp->cleanfaxdata); } if (TIFFFieldSet(tif,FIELD_BADFAXLINES)) fprintf(fd, " Bad Fax Lines: %lu\n", (u_long) sp->badfaxlines); if (TIFFFieldSet(tif,FIELD_BADFAXRUN)) fprintf(fd, " Consecutive Bad Fax Lines: %lu\n", (u_long) sp->badfaxrun); if (TIFFFieldSet(tif,FIELD_RECVPARAMS)) fprintf(fd, " Fax Receive Parameters: %08lx\n", (u_long) sp->recvparams); if (TIFFFieldSet(tif,FIELD_SUBADDRESS)) fprintf(fd, " Fax SubAddress: %s\n", sp->subaddress); if (TIFFFieldSet(tif,FIELD_RECVTIME)) fprintf(fd, " Fax Receive Time: %lu secs\n", (u_long) sp->recvtime);}static intInitCCITTFax3(TIFF* tif){ Fax3BaseState* sp; /* * Allocate state block so tag methods have storage to record values. */ if (tif->tif_mode == O_RDONLY) tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (Fax3DecodeState)); else tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (Fax3EncodeState)); if (tif->tif_data == NULL) { TIFFError("TIFFInitCCITTFax3", "%s: No space for state block", tif->tif_name); return (0); } sp = Fax3State(tif); sp->rw_mode = tif->tif_mode; /* * Merge codec-specific tag information and * override parent get/set field methods. */ _TIFFMergeFieldInfo(tif, faxFieldInfo, N(faxFieldInfo)); sp->vgetparent = tif->tif_vgetfield; tif->tif_vgetfield = Fax3VGetField; /* hook for codec tags */ sp->vsetparent = tif->tif_vsetfield; tif->tif_vsetfield = Fax3VSetField; /* hook for codec tags */ tif->tif_printdir = Fax3PrintDir; /* hook for codec tags */ sp->groupoptions = 0; sp->recvparams = 0; sp->subaddress = NULL; if (sp->rw_mode == O_RDONLY) { tif->tif_flags |= TIFF_NOBITREV;/* decoder does bit reversal */ DecoderState(tif)->runs = NULL; TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns); } else EncoderState(tif)->refline = NULL; /* * Install codec methods. */ tif->tif_setupdecode = Fax3SetupState; tif->tif_predecode = Fax3PreDecode; tif->tif_decoderow = Fax3Decode1D; tif->tif_decodestrip = Fax3Decode1D; tif->tif_decodetile = Fax3Decode1D; tif->tif_setupencode = Fax3SetupState; tif->tif_preencode = Fax3PreEncode; tif->tif_postencode = Fax3PostEncode; tif->tif_encoderow = Fax3Encode; tif->tif_encodestrip = Fax3Encode; tif->tif_encodetile = Fax3Encode; tif->tif_close = Fax3Close; tif->tif_cleanup = Fax3Cleanup; return (1);}intTIFFInitCCITTFax3(TIFF* tif, int scheme){ if (InitCCITTFax3(tif)) { _TIFFMergeFieldInfo(tif, fax3FieldInfo, N(fax3FieldInfo)); /* * The default format is Class/F-style w/o RTC. */ return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); } else return (0);}/* * CCITT Group 4 (T.6) Facsimile-compatible * Compression Scheme Support. */#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; }/* * Decode the requested amount of G4-encoded data. */static intFax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s){ DECLARE_STATE_2D(tif, sp, "Fax4Decode"); (void) s; CACHE_STATE(tif, sp); while ((long)occ > 0) { a0 = 0; RunLength = 0; pa = thisrun = sp->curruns; pb = sp->refruns; b1 = *pb++;#ifdef FAX3_DEBUG printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); printf("-------------------- %d\n", tif->tif_row); fflush(stdout);#endif EXPAND2D(EOFG4); if (EOLcnt) goto EOFG4; (*sp->fill)(buf, thisrun, pa, lastx); SETVAL(0); /* imaginary change for reference */ SWAP(uint32*, sp->curruns, sp->refruns); buf += sp->b.rowbytes; occ -= sp->b.rowbytes; if (occ != 0) tif->tif_row++; continue; EOFG4: NeedBits16( 13, BADG4 ); BADG4:#ifdef FAX3_DEBUG if( GetBits(13) != 0x1001 ) fputs( "Bad RTC\n", stderr );#endif ClrBits( 13 ); (*sp->fill)(buf, thisrun, pa, lastx); UNCACHE_STATE(tif, sp); return (-1); } UNCACHE_STATE(tif, sp); return (1);}#undef SWAP/* * Encode the requested amount of data. */static intFax4Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s){ Fax3EncodeState *sp = EncoderState(tif); (void) s; while ((long)cc > 0) { if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) return (0); _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); bp += sp->b.rowbytes; cc -= sp->b.rowbytes; if (cc != 0) tif->tif_row++; } return (1);}static intFax4PostEncode(TIFF* tif){ Fax3EncodeState *sp = EncoderState(tif); /* terminate strip w/ EOFB */ Fax3PutBits(tif, EOL, 12); Fax3PutBits(tif, EOL, 12); if (sp->bit != 8) Fax3FlushBits(tif, sp); return (1);}intTIFFInitCCITTFax4(TIFF* tif, int scheme){ if (InitCCITTFax3(tif)) { /* reuse G3 support */ _TIFFMergeFieldInfo(tif, fax4FieldInfo, N(fax4FieldInfo)); tif->tif_decoderow = Fax4Decode; tif->tif_decodestrip = Fax4Decode; tif->tif_decodetile = Fax4Decode; tif->tif_encoderow = Fax4Encode; tif->tif_encodestrip = Fax4Encode; tif->tif_encodetile = Fax4Encode; tif->tif_postencode = Fax4PostEncode; /* * Suppress RTC at the end of each strip. */ return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC); } else return (0);}/* * CCITT Group 3 1-D Modified Huffman RLE Compression Support. * (Compression algorithms 2 and 32771) *//* * Decode the requested amount of RLE-encoded data. */static intFax3DecodeRLE(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s){ DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); int mode = sp->b.mode; (void) s; CACHE_STATE(tif, sp); thisrun = sp->curruns; while ((long)occ > 0) { a0 = 0; RunLength = 0; pa = thisrun;#ifdef FAX3_DEBUG printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); printf("-------------------- %d\n", tif->tif_row); fflush(stdout);#endif EXPAND1D(EOFRLE); (*sp->fill)(buf, thisrun, pa, lastx); /* * Cleanup at the end of the row. */ if (mode & FAXMODE_BYTEALIGN) { int n = BitsAvail - (BitsAvail &~ 7); ClrBits(n); } else if (mode & FAXMODE_WORDALIGN) { int n = BitsAvail - (BitsAvail &~ 15); ClrBits(n); if (BitsAvail == 0 && !isAligned(cp, uint16)) cp++; } buf += sp->b.rowbytes; occ -= sp->b.rowbytes; if (occ != 0) tif->tif_row++; continue; EOFRLE: /* premature EOF */ (*sp->fill)(buf, thisrun, pa, lastx); UNCACHE_STATE(tif, sp); return (-1); } UNCACHE_STATE(tif, sp); return (1);}intTIFFInitCCITTRLE(TIFF* tif, int scheme){ if (InitCCITTFax3(tif)) { /* reuse G3 support */ tif->tif_decoderow = Fax3DecodeRLE; tif->tif_decodestrip = Fax3DecodeRLE; tif->tif_decodetile = Fax3DecodeRLE; /* * Suppress RTC+EOLs when encoding and byte-align data. */ return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN); } else return (0);}intTIFFInitCCITTRLEW(TIFF* tif, int scheme){ if (InitCCITTFax3(tif)) { /* reuse G3 support */ tif->tif_decoderow = Fax3DecodeRLE; tif->tif_decodestrip = Fax3DecodeRLE; tif->tif_decodetile = Fax3DecodeRLE; /* * Suppress RTC+EOLs when encoding and word-align data. */ return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN); } else return (0);}#endif /* CCITT_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -