?? tif_fax3.c
字號:
Fax3Close(TIFF* tif){ if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) { Fax3CodecState* sp = EncoderState(tif); unsigned int code = EOL; unsigned 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){ Fax3CodecState* sp = DecoderState(tif); assert(sp != 0); tif->tif_tagmethods.vgetfield = sp->b.vgetparent; tif->tif_tagmethods.vsetfield = sp->b.vsetparent; tif->tif_tagmethods.printdir = sp->b.printdir; if (sp->runs) _TIFFfree(sp->runs); if (sp->refline) _TIFFfree(sp->refline); if (Fax3State(tif)->subaddress) _TIFFfree(Fax3State(tif)->subaddress); _TIFFfree(tif->tif_data); tif->tif_data = NULL; _TIFFSetDefaultCompressionState(tif);}#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_FAXDCS (FIELD_CODEC+6)#define FIELD_OPTIONS (FIELD_CODEC+7)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" }, { TIFFTAG_FAXDCS, -1,-1, TIFF_ASCII, FIELD_FAXDCS, TRUE, FALSE, "FaxDcs" },};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); const TIFFFieldInfo* fip; assert(sp != 0); assert(sp->vsetparent != 0); switch (tag) { case TIFFTAG_FAXMODE: sp->mode = va_arg(ap, int); return 1; /* NB: pseudo tag */ case TIFFTAG_FAXFILLFUNC: DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); return 1; /* NB: pseudo tag */ case TIFFTAG_GROUP3OPTIONS: /* XXX: avoid reading options if compression mismatches. */ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) sp->groupoptions = va_arg(ap, uint32); break; case TIFFTAG_GROUP4OPTIONS: /* XXX: avoid reading options if compression mismatches. */ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) 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; case TIFFTAG_FAXDCS: _TIFFsetString(&sp->faxdcs, va_arg(ap, char*)); break; default: return (*sp->vsetparent)(tif, tag, ap); } if ((fip = _TIFFFieldWithTag(tif, tag))) TIFFSetFieldBit(tif, fip->field_bit); else return 0; tif->tif_flags |= TIFF_DIRTYDIRECT; return 1;}static intFax3VGetField(TIFF* tif, ttag_t tag, va_list ap){ Fax3BaseState* sp = Fax3State(tif); assert(sp != 0); switch (tag) { case TIFFTAG_FAXMODE: *va_arg(ap, int*) = sp->mode; break; case TIFFTAG_FAXFILLFUNC: *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; case TIFFTAG_FAXDCS: *va_arg(ap, char**) = sp->faxdcs; break; default: return (*sp->vgetparent)(tif, tag, ap); } return (1);}static voidFax3PrintDir(TIFF* tif, FILE* fd, long flags){ Fax3BaseState* sp = Fax3State(tif); assert(sp != 0); (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", (unsigned long) sp->groupoptions, (unsigned 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", (unsigned long) sp->badfaxlines); if (TIFFFieldSet(tif,FIELD_BADFAXRUN)) fprintf(fd, " Consecutive Bad Fax Lines: %lu\n", (unsigned long) sp->badfaxrun); if (TIFFFieldSet(tif,FIELD_RECVPARAMS)) fprintf(fd, " Fax Receive Parameters: %08lx\n", (unsigned 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", (unsigned long) sp->recvtime); if (TIFFFieldSet(tif,FIELD_FAXDCS)) fprintf(fd, " Fax DCS: %s\n", sp->faxdcs);}static intInitCCITTFax3(TIFF* tif){ Fax3BaseState* sp; /* * Allocate state block so tag methods have storage to record values. */ tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (Fax3CodecState)); if (tif->tif_data == NULL) { TIFFErrorExt(tif->tif_clientdata, "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_tagmethods.vgetfield; tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */ sp->vsetparent = tif->tif_tagmethods.vsetfield; tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */ sp->printdir = tif->tif_tagmethods.printdir; tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */ sp->groupoptions = 0; sp->recvparams = 0; sp->subaddress = NULL; sp->faxdcs = NULL; if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */ tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */ DecoderState(tif)->runs = NULL; TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns); 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){ (void) 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); SETVALUE(0); /* imaginary change for reference */ SWAP(uint32*, sp->curruns, sp->refruns); buf += sp->b.rowbytes; occ -= sp->b.rowbytes; sp->line++; 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){ Fax3CodecState *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; } return (1);}static intFax4PostEncode(TIFF* tif){ Fax3CodecState *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){ (void) 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; sp->line++; 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){ (void) 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){ (void) 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 *//* vim: set ts=8 sts=8 sw=8 noet: */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -