X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8414a40c52191d4c7cfeea74df22d9d64cbec415..6f026b5b63fe7ccb025e84509886f74772b9df13:/src/tiff/libtiff/tif_fax3.c diff --git a/src/tiff/libtiff/tif_fax3.c b/src/tiff/libtiff/tif_fax3.c index ed05633296..0ff36120a3 100644 --- a/src/tiff/libtiff/tif_fax3.c +++ b/src/tiff/libtiff/tif_fax3.c @@ -1,4 +1,3 @@ -/* $Id$ */ /* * Copyright (c) 1990-1997 Sam Leffler @@ -48,21 +47,19 @@ * derived from this ``base state'' block. */ typedef struct { - int rw_mode; /* O_RDONLY for decode, else encode */ - int mode; /* operating mode */ - uint32 rowbytes; /* bytes in a decoded scanline */ - uint32 rowpixels; /* pixels in a scanline */ - - uint16 cleanfaxdata; /* CleanFaxData tag */ - uint32 badfaxrun; /* BadFaxRun tag */ - uint32 badfaxlines; /* BadFaxLines tag */ - uint32 groupoptions; /* Group 3/4 options tag */ - uint32 recvparams; /* encoded Class 2 session params */ - char* subaddress; /* subaddress string */ - uint32 recvtime; /* time spent receiving (secs) */ - char* faxdcs; /* Table 2/T.30 encoded session params */ - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + int rw_mode; /* O_RDONLY for decode, else encode */ + int mode; /* operating mode */ + tmsize_t rowbytes; /* bytes in a decoded scanline */ + uint32 rowpixels; /* pixels in a scanline */ + + uint16 cleanfaxdata; /* CleanFaxData tag */ + uint32 badfaxrun; /* BadFaxRun tag */ + uint32 badfaxlines; /* BadFaxLines tag */ + uint32 groupoptions; /* Group 3/4 options tag */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ } Fax3BaseState; #define Fax3State(tif) ((Fax3BaseState*) (tif)->tif_data) @@ -85,13 +82,14 @@ typedef struct { unsigned char* refline; /* reference line for 2d decoding */ int k; /* #rows left that can be 2d encoded */ int maxk; /* max #rows that can be 2d encoded */ + + int line; } Fax3CodecState; -#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif)) -#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif)) +#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif)) +#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif)) -#define is2DEncoding(sp) \ - (sp->b.groupoptions & GROUP3OPT_2DENCODING) -#define isAligned(p,t) ((((unsigned long)(p)) & (sizeof (t)-1)) == 0) +#define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING) +#define isAligned(p,t) ((((size_t)(p)) & (sizeof (t)-1)) == 0) /* * Group 3 and Group 4 Decoding. @@ -137,15 +135,15 @@ typedef struct { sp->bit = BitsAvail; \ sp->data = BitAcc; \ sp->EOLcnt = EOLcnt; \ - tif->tif_rawcc -= (tidata_t) cp - tif->tif_rawcp; \ - tif->tif_rawcp = (tidata_t) cp; \ + tif->tif_rawcc -= (tmsize_t)((uint8*) cp - tif->tif_rawcp); \ + tif->tif_rawcp = (uint8*) cp; \ } while (0) /* * Setup state for decoding a strip. */ static int -Fax3PreDecode(TIFF* tif, tsample_t s) +Fax3PreDecode(TIFF* tif, uint16 s) { Fax3CodecState* sp = DecoderState(tif); @@ -167,6 +165,7 @@ Fax3PreDecode(TIFF* tif, tsample_t s) sp->refruns[0] = (uint32) sp->b.rowpixels; sp->refruns[1] = 0; } + sp->line = 0; return (1); } @@ -179,46 +178,44 @@ Fax3PreDecode(TIFF* tif, tsample_t s) static void Fax3Unexpected(const char* module, TIFF* tif, uint32 line, uint32 a0) { - TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad code word at line %lu of %s %lu (x %lu)", - tif->tif_name, (unsigned long) line, isTiled(tif) ? "tile" : "strip", - (unsigned long) (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - (unsigned long) a0); + TIFFErrorExt(tif->tif_clientdata, module, "Bad code word at line %u of %s %u (x %u)", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0); } -#define unexpected(table, a0) Fax3Unexpected(module, tif, line, a0) +#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0) static void Fax3Extension(const char* module, TIFF* tif, uint32 line, uint32 a0) { TIFFErrorExt(tif->tif_clientdata, module, - "%s: Uncompressed data (not supported) at line %lu of %s %lu (x %lu)", - tif->tif_name, (unsigned long) line, isTiled(tif) ? "tile" : "strip", - (unsigned long) (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - (unsigned long) a0); + "Uncompressed data (not supported) at line %u of %s %u (x %u)", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0); } -#define extension(a0) Fax3Extension(module, tif, line, a0) +#define extension(a0) Fax3Extension(module, tif, sp->line, a0) static void Fax3BadLength(const char* module, TIFF* tif, uint32 line, uint32 a0, uint32 lastx) { - TIFFWarningExt(tif->tif_clientdata, module, "%s: %s at line %lu of %s %lu (got %lu, expected %lu)", - tif->tif_name, + TIFFWarningExt(tif->tif_clientdata, module, "%s at line %u of %s %u (got %u, expected %u)", a0 < lastx ? "Premature EOL" : "Line length mismatch", - (unsigned long) line, isTiled(tif) ? "tile" : "strip", - (unsigned long) (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - (unsigned long) a0, lastx); + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0, lastx); } -#define badlength(a0,lastx) Fax3BadLength(module, tif, line, a0, lastx) +#define badlength(a0,lastx) Fax3BadLength(module, tif, sp->line, a0, lastx) static void Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0) { - TIFFWarningExt(tif->tif_clientdata, module, "%s: Premature EOF at line %lu of %s %lu (x %lu)", - tif->tif_name, - (unsigned long) line, isTiled(tif) ? "tile" : "strip", - (unsigned long) (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - (unsigned long) a0); + TIFFWarningExt(tif->tif_clientdata, module, "Premature EOF at line %u of %s %u (x %u)", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), + a0); } -#define prematureEOF(a0) Fax3PrematureEOF(module, tif, line, a0) +#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0) #define Nop @@ -226,15 +223,18 @@ Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0) * Decode the requested amount of G3 1D-encoded data. */ static int -Fax3Decode1D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { DECLARE_STATE(tif, sp, "Fax3Decode1D"); - int line = 0; - (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } CACHE_STATE(tif, sp); thisrun = sp->curruns; - while ((long)occ > 0) { + while (occ > 0) { a0 = 0; RunLength = 0; pa = thisrun; @@ -248,7 +248,7 @@ Fax3Decode1D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) (*sp->fill)(buf, thisrun, pa, lastx); buf += sp->b.rowbytes; occ -= sp->b.rowbytes; - line++; + sp->line++; continue; EOF1D: /* premature EOF */ CLEANUP_RUNS(); @@ -266,15 +266,18 @@ Fax3Decode1D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) * Decode the requested amount of G3 2D-encoded data. */ static int -Fax3Decode2D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { DECLARE_STATE_2D(tif, sp, "Fax3Decode2D"); - int line = 0; int is1D; /* current line is 1d/2d-encoded */ - (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } CACHE_STATE(tif, sp); - while ((long)occ > 0) { + while (occ > 0) { a0 = 0; RunLength = 0; pa = thisrun = sp->curruns; @@ -302,7 +305,7 @@ Fax3Decode2D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) SWAP(uint32*, sp->curruns, sp->refruns); buf += sp->b.rowbytes; occ -= sp->b.rowbytes; - line++; + sp->line++; continue; EOF2D: /* premature EOF */ CLEANUP_RUNS(); @@ -322,7 +325,7 @@ Fax3Decode2D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) * this is <8 bytes. We optimize the code here to reflect the * machine characteristics. */ -#if SIZEOF_LONG == 8 +#if SIZEOF_UNSIGNED_LONG == 8 # define FILL(n, cp) \ switch (n) { \ case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\ @@ -450,6 +453,13 @@ _TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) #undef ZERO #undef FILL +static int +Fax3FixupTags(TIFF* tif) +{ + (void) tif; + return (1); +} + /* * Setup G3/G4-related compression/decompression state * before data is processed. This routine is called once @@ -460,14 +470,16 @@ _TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) static int Fax3SetupState(TIFF* tif) { + static const char module[] = "Fax3SetupState"; TIFFDirectory* td = &tif->tif_dir; Fax3BaseState* sp = Fax3State(tif); int needsRefLine; Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif); - uint32 rowbytes, rowpixels, nruns; + tmsize_t rowbytes; + uint32 rowpixels, nruns; if (td->td_bitspersample != 1) { - TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + TIFFErrorExt(tif->tif_clientdata, module, "Bits/sample must be 1 for Group 3/4 encoding/decoding"); return (0); } @@ -481,8 +493,8 @@ Fax3SetupState(TIFF* tif) rowbytes = TIFFScanlineSize(tif); rowpixels = td->td_imagewidth; } - sp->rowbytes = (uint32) rowbytes; - sp->rowpixels = (uint32) rowpixels; + sp->rowbytes = rowbytes; + sp->rowpixels = rowpixels; /* * Allocate any additional space required for decoding/encoding. */ @@ -491,15 +503,32 @@ Fax3SetupState(TIFF* tif) td->td_compression == COMPRESSION_CCITTFAX4 ); - nruns = needsRefLine ? 2*TIFFroundup(rowpixels,32) : rowpixels; - - dsp->runs = (uint32*) _TIFFCheckMalloc(tif, 2*nruns+3, sizeof (uint32), - "for Group 3/4 run arrays"); + /* + Assure that allocation computations do not overflow. + + TIFFroundup and TIFFSafeMultiply return zero on integer overflow + */ + dsp->runs=(uint32*) NULL; + nruns = TIFFroundup_32(rowpixels,32); + if (needsRefLine) { + nruns = TIFFSafeMultiply(uint32,nruns,2); + } + if ((nruns == 0) || (TIFFSafeMultiply(uint32,nruns,2) == 0)) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Row pixels integer overflow (rowpixels %u)", + rowpixels); + return (0); + } + dsp->runs = (uint32*) _TIFFCheckMalloc(tif, + TIFFSafeMultiply(uint32,nruns,2), + sizeof (uint32), + "for Group 3/4 run arrays"); if (dsp->runs == NULL) return (0); + memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32)); dsp->curruns = dsp->runs; if (needsRefLine) - dsp->refruns = dsp->runs + (nruns>>1); + dsp->refruns = dsp->runs + nruns; else dsp->refruns = NULL; if (td->td_compression == COMPRESSION_CCITTFAX3 @@ -520,9 +549,8 @@ Fax3SetupState(TIFF* tif) */ esp->refline = (unsigned char*) _TIFFmalloc(rowbytes); if (esp->refline == NULL) { - TIFFErrorExt(tif->tif_clientdata, "Fax3SetupState", - "%s: No space for Group 3/4 reference line", - tif->tif_name); + TIFFErrorExt(tif->tif_clientdata, module, + "No space for Group 3/4 reference line"); return (0); } } else /* 1d encoding */ @@ -538,14 +566,14 @@ Fax3SetupState(TIFF* tif) #define Fax3FlushBits(tif, sp) { \ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ (void) TIFFFlushData1(tif); \ - *(tif)->tif_rawcp++ = (tidataval_t) (sp)->data; \ + *(tif)->tif_rawcp++ = (uint8) (sp)->data; \ (tif)->tif_rawcc++; \ (sp)->data = 0, (sp)->bit = 8; \ } #define _FlushBits(tif) { \ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ (void) TIFFFlushData1(tif); \ - *(tif)->tif_rawcp++ = (tidataval_t) data; \ + *(tif)->tif_rawcp++ = (uint8) data; \ (tif)->tif_rawcc++; \ data = 0, bit = 8; \ } @@ -557,6 +585,7 @@ static const int _msbmask[9] = length -= bit; \ _FlushBits(tif); \ } \ + assert( length < 9 ); \ data |= (bits & _msbmask[length]) << (bit - length); \ bit -= length; \ if (bit == 0) \ @@ -684,7 +713,7 @@ Fax3PutEOL(TIFF* tif) * Reset encoding state at the start of a strip. */ static int -Fax3PreEncode(TIFF* tif, tsample_t s) +Fax3PreEncode(TIFF* tif, uint16 s) { Fax3CodecState* sp = EncoderState(tif); @@ -718,6 +747,7 @@ Fax3PreEncode(TIFF* tif, tsample_t s) sp->k = sp->maxk-1; } else sp->k = sp->maxk = 0; + sp->line = 0; return (1); } @@ -1004,12 +1034,17 @@ Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits) * Encode a buffer of pixels. */ static int -Fax3Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +Fax3Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { + static const char module[] = "Fax3Encode"; Fax3CodecState* sp = EncoderState(tif); - (void) s; - while ((long)cc > 0) { + if (cc % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) { if ((sp->b.mode & FAXMODE_NOEOL) == 0) Fax3PutEOL(tif); if (is2DEncoding(sp)) { @@ -1019,7 +1054,7 @@ Fax3Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) sp->tag = G3_2D; } else { if (!Fax3Encode2DRow(tif, bp, sp->refline, - sp->b.rowpixels)) + sp->b.rowpixels)) return (0); sp->k--; } @@ -1074,14 +1109,13 @@ Fax3Cleanup(TIFF* tif) 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; @@ -1091,106 +1125,77 @@ Fax3Cleanup(TIFF* 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 TIFFField faxFields[] = { + { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL }, + { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL }, + { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL }, + { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL }, + { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL }}; +static const TIFFField fax3Fields[] = { + { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL }, }; -static const TIFFFieldInfo fax3FieldInfo[] = { - { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, FIELD_OPTIONS, - FALSE, FALSE, "Group3Options" }, +static const TIFFField fax4Fields[] = { + { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL }, }; -static const TIFFFieldInfo fax4FieldInfo[] = { - { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, FIELD_OPTIONS, - FALSE, FALSE, "Group4Options" }, -}; -#define N(a) (sizeof (a) / sizeof (a[0])) static int -Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap) +Fax3VSetField(TIFF* tif, uint32 tag, va_list ap) { Fax3BaseState* sp = Fax3State(tif); + const TIFFField* fip; assert(sp != 0); assert(sp->vsetparent != 0); switch (tag) { case TIFFTAG_FAXMODE: - sp->mode = va_arg(ap, int); - return (1); /* NB: pseudo tag */ + sp->mode = (int) va_arg(ap, int); + return 1; /* NB: pseudo tag */ case TIFFTAG_FAXFILLFUNC: DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); - return (1); /* NB: pseudo tag */ + 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); + sp->groupoptions = (uint32) 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); + sp->groupoptions = (uint32) va_arg(ap, uint32); break; case TIFFTAG_BADFAXLINES: - sp->badfaxlines = va_arg(ap, uint32); + sp->badfaxlines = (uint32) va_arg(ap, uint32); break; case TIFFTAG_CLEANFAXDATA: - sp->cleanfaxdata = (uint16) va_arg(ap, int); + sp->cleanfaxdata = (uint16) va_arg(ap, uint16_vap); 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*)); + sp->badfaxrun = (uint32) va_arg(ap, uint32); break; default: return (*sp->vsetparent)(tif, tag, ap); } - TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); + + if ((fip = TIFFFieldWithTag(tif, tag))) + TIFFSetFieldBit(tif, fip->field_bit); + else + return 0; + tif->tif_flags |= TIFF_DIRTYDIRECT; - return (1); + return 1; } static int -Fax3VGetField(TIFF* tif, ttag_t tag, va_list ap) +Fax3VGetField(TIFF* tif, uint32 tag, va_list ap) { Fax3BaseState* sp = Fax3State(tif); + assert(sp != 0); + switch (tag) { case TIFFTAG_FAXMODE: *va_arg(ap, int*) = sp->mode; @@ -1211,18 +1216,6 @@ Fax3VGetField(TIFF* tif, ttag_t tag, va_list ap) 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); } @@ -1234,6 +1227,8 @@ Fax3PrintDir(TIFF* tif, FILE* fd, long flags) { Fax3BaseState* sp = Fax3State(tif); + assert(sp != 0); + (void) flags; if (TIFFFieldSet(tif,FIELD_OPTIONS)) { const char* sep = " "; @@ -1277,32 +1272,34 @@ Fax3PrintDir(TIFF* tif, FILE* fd, long flags) 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); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); } static int InitCCITTFax3(TIFF* tif) { + static const char module[] = "InitCCITTFax3"; Fax3BaseState* sp; + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) { + TIFFErrorExt(tif->tif_clientdata, "InitCCITTFax3", + "Merging common CCITT Fax codec-specific tags failed"); + return 0; + } + /* * Allocate state block so tag methods have storage to record values. */ - tif->tif_data = (tidata_t) + tif->tif_data = (uint8*) _TIFFmalloc(sizeof (Fax3CodecState)); if (tif->tif_data == NULL) { - TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3", - "%s: No space for state block", tif->tif_name); + TIFFErrorExt(tif->tif_clientdata, module, + "No space for state block"); return (0); } @@ -1310,19 +1307,15 @@ InitCCITTFax3(TIFF* tif) sp->rw_mode = tif->tif_mode; /* - * Merge codec-specific tag information and - * override parent get/set field methods. + * 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 */ @@ -1333,6 +1326,7 @@ InitCCITTFax3(TIFF* tif) /* * Install codec methods. */ + tif->tif_fixuptags = Fax3FixupTags; tif->tif_setupdecode = Fax3SetupState; tif->tif_predecode = Fax3PreDecode; tif->tif_decoderow = Fax3Decode1D; @@ -1355,14 +1349,22 @@ TIFFInitCCITTFax3(TIFF* tif, int scheme) { (void) scheme; if (InitCCITTFax3(tif)) { - _TIFFMergeFieldInfo(tif, fax3FieldInfo, N(fax3FieldInfo)); + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, fax3Fields, + TIFFArrayCount(fax3Fields))) { + TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3", + "Merging CCITT Fax 3 codec-specific tags failed"); + return 0; + } /* * The default format is Class/F-style w/o RTC. */ return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); } else - return (0); + return 01; } /* @@ -1370,19 +1372,22 @@ TIFFInitCCITTFax3(TIFF* tif, int scheme) * Compression Scheme Support. */ -#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } /* * Decode the requested amount of G4-encoded data. */ static int -Fax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { DECLARE_STATE_2D(tif, sp, "Fax4Decode"); - int line = 0; - (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } CACHE_STATE(tif, sp); - while ((long)occ > 0) { + while (occ > 0) { a0 = 0; RunLength = 0; pa = thisrun = sp->curruns; @@ -1401,19 +1406,19 @@ Fax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) SWAP(uint32*, sp->curruns, sp->refruns); buf += sp->b.rowbytes; occ -= sp->b.rowbytes; - line++; + sp->line++; continue; EOFG4: NeedBits16( 13, BADG4 ); BADG4: #ifdef FAX3_DEBUG if( GetBits(13) != 0x1001 ) - fputs( "Bad RTC\n", stderr ); + fputs( "Bad EOFB\n", stderr ); #endif ClrBits( 13 ); (*sp->fill)(buf, thisrun, pa, lastx); UNCACHE_STATE(tif, sp); - return (-1); + return ( sp->line ? 1 : -1); /* don't error on badly-terminated strips */ } UNCACHE_STATE(tif, sp); return (1); @@ -1424,12 +1429,17 @@ Fax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) * Encode the requested amount of data. */ static int -Fax4Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +Fax4Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { + static const char module[] = "Fax4Encode"; Fax3CodecState *sp = EncoderState(tif); - (void) s; - while ((long)cc > 0) { + if (cc % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) { if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) return (0); _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); @@ -1457,7 +1467,15 @@ TIFFInitCCITTFax4(TIFF* tif, int scheme) { (void) scheme; if (InitCCITTFax3(tif)) { /* reuse G3 support */ - _TIFFMergeFieldInfo(tif, fax4FieldInfo, N(fax4FieldInfo)); + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, fax4Fields, + TIFFArrayCount(fax4Fields))) { + TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax4", + "Merging CCITT Fax 4 codec-specific tags failed"); + return 0; + } tif->tif_decoderow = Fax4Decode; tif->tif_decodestrip = Fax4Decode; @@ -1483,16 +1501,19 @@ TIFFInitCCITTFax4(TIFF* tif, int scheme) * Decode the requested amount of RLE-encoded data. */ static int -Fax3DecodeRLE(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +Fax3DecodeRLE(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) { DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); int mode = sp->b.mode; - int line = 0; - (void) s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); + return (-1); + } CACHE_STATE(tif, sp); thisrun = sp->curruns; - while ((long)occ > 0) { + while (occ > 0) { a0 = 0; RunLength = 0; pa = thisrun; @@ -1517,7 +1538,7 @@ Fax3DecodeRLE(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) } buf += sp->b.rowbytes; occ -= sp->b.rowbytes; - line++; + sp->line++; continue; EOFRLE: /* premature EOF */ (*sp->fill)(buf, thisrun, pa, lastx); @@ -1552,7 +1573,7 @@ TIFFInitCCITTRLEW(TIFF* tif, int scheme) if (InitCCITTFax3(tif)) { /* reuse G3 support */ tif->tif_decoderow = Fax3DecodeRLE; tif->tif_decodestrip = Fax3DecodeRLE; - tif->tif_decodetile = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; /* * Suppress RTC+EOLs when encoding and word-align data. */ @@ -1564,3 +1585,10 @@ TIFFInitCCITTRLEW(TIFF* tif, int scheme) #endif /* CCITT_SUPPORT */ /* vim: set ts=8 sts=8 sw=8 noet: */ +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */