#include <assert.h>
#include <stdio.h>
-/*
- * NB: define PURIFY if you're using purify and you want
- * to avoid some harmless array bounds complaints that
- * can happen in the _TIFFFax3fillruns routine.
- */
-
/*
* Compression+decompression state blocks are
* 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 */
} Fax3BaseState;
#define Fax3State(tif) ((Fax3BaseState*) (tif)->tif_data)
+typedef enum { G3_1D, G3_2D } Ttag;
typedef struct {
Fax3BaseState b;
+
+ /* Decoder state info */
const u_char* bitmap; /* bit reversal table */
uint32 data; /* current i/o byte/word */
int bit; /* current i/o bit in byte */
uint32* runs; /* b&w runs for current/previous row */
uint32* refruns; /* runs for reference line */
uint32* curruns; /* runs for current line */
-} Fax3DecodeState;
-#define DecoderState(tif) ((Fax3DecodeState*) Fax3State(tif))
-typedef struct {
- Fax3BaseState b;
- int data; /* current i/o byte */
- int bit; /* current i/o bit in byte */
- enum { G3_1D, G3_2D } tag; /* encoding state */
+ /* Encoder state info */
+ Ttag tag; /* encoding state */
u_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 */
-} Fax3EncodeState;
-#define EncoderState(tif) ((Fax3EncodeState*) Fax3State(tif))
+} Fax3CodecState;
+#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif))
+#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif))
#define is2DEncoding(sp) \
(sp->b.groupoptions & GROUP3OPT_2DENCODING)
*/
#define DECLARE_STATE(tif, sp, mod) \
static const char module[] = mod; \
- Fax3DecodeState* sp = DecoderState(tif); \
+ Fax3CodecState* sp = DecoderState(tif); \
int a0; /* reference element */ \
int lastx = sp->b.rowpixels; /* last element in row */ \
uint32 BitAcc; /* bit accumulator */ \
static int
Fax3PreDecode(TIFF* tif, tsample_t s)
{
- Fax3DecodeState* sp = DecoderState(tif);
+ Fax3CodecState* sp = DecoderState(tif);
(void) s;
assert(sp != NULL);
sp->bitmap =
TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
if (sp->refruns) { /* init reference line to white */
- sp->refruns[0] = sp->b.rowpixels;
+ sp->refruns[0] = (uint32) sp->b.rowpixels;
sp->refruns[1] = 0;
}
return (1);
(*sp->fill)(buf, thisrun, pa, lastx);
buf += sp->b.rowbytes;
occ -= sp->b.rowbytes;
- if (occ != 0)
- tif->tif_row++;
continue;
EOF1D: /* premature EOF */
CLEANUP_RUNS();
SWAP(uint32*, sp->curruns, sp->refruns);
buf += sp->b.rowbytes;
occ -= sp->b.rowbytes;
- if (occ != 0)
- tif->tif_row++;
continue;
EOF2D: /* premature EOF */
CLEANUP_RUNS();
* this is <8 bytes. We optimize the code here to reflect the
* machine characteristics.
*/
-#if defined(__alpha) || _MIPS_SZLONG == 64
+#if defined(__alpha) || _MIPS_SZLONG == 64 || defined(__LP64__) || defined(__arch64__)
#define FILL(n, cp) \
switch (n) { \
case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\
x = 0;
for (; runs < erun; runs += 2) {
run = runs[0];
- if (x+run > lastx)
- run = runs[0] = lastx - x;
+ if (x+run > lastx || run > lastx )
+ run = runs[0] = (uint32) (lastx - x);
if (run) {
cp = buf + (x>>3);
bx = x&7;
ZERO(n, cp);
run &= 7;
}
-#ifdef PURIFY
if (run)
cp[0] &= 0xff >> run;
-#else
- cp[0] &= 0xff >> run;
-#endif
} else
cp[0] &= ~(_fillmasks[run]>>bx);
x += runs[0];
}
run = runs[1];
- if (x+run > lastx)
+ if (x+run > lastx || run > lastx )
run = runs[1] = lastx - x;
if (run) {
cp = buf + (x>>3);
FILL(n, cp);
run &= 7;
}
-#ifdef PURIFY
if (run)
cp[0] |= 0xff00 >> run;
-#else
- cp[0] |= 0xff00 >> run;
-#endif
} else
cp[0] |= _fillmasks[run]>>bx;
x += runs[1];
#undef ZERO
#undef FILL
+static char *
+CheckMalloc(TIFF* tif, size_t nmemb, size_t elem_size, const char* what)
+{
+ char *cp = NULL;
+ tsize_t bytes = nmemb * elem_size;
+
+ if (nmemb && elem_size && bytes / elem_size == nmemb)
+ cp = (char*) _TIFFmalloc(bytes);
+
+ if (cp == NULL)
+ TIFFError(tif->tif_name, "No space %s", what);
+
+ return (cp);
+}
+
/*
* Setup G3/G4-related compression/decompression state
* before data is processed. This routine is called once
Fax3BaseState* sp = Fax3State(tif);
long rowbytes, rowpixels;
int needsRefLine;
+ Fax3CodecState* dsp = DecoderState(tif);
+ uint32 nruns;
if (td->td_bitspersample != 1) {
TIFFError(tif->tif_name,
(sp->groupoptions & GROUP3OPT_2DENCODING) ||
td->td_compression == COMPRESSION_CCITTFAX4
);
- if (tif->tif_mode == O_RDONLY) { /* 1d/2d decoding */
- Fax3DecodeState* dsp = DecoderState(tif);
- uint32 nruns = needsRefLine ?
- 2*TIFFroundup(rowpixels,32) : rowpixels;
- dsp->runs = (uint32*) _TIFFmalloc(nruns*sizeof (uint16));
- if (dsp->runs == NULL) {
- TIFFError("Fax3SetupState",
- "%s: No space for Group 3/4 run arrays",
- tif->tif_name);
- return (0);
- }
- dsp->curruns = dsp->runs;
- if (needsRefLine)
- dsp->refruns = dsp->runs + (nruns>>1);
- else
- dsp->refruns = NULL;
- if (is2DEncoding(dsp)) { /* NB: default is 1D routine */
- tif->tif_decoderow = Fax3Decode2D;
- tif->tif_decodestrip = Fax3Decode2D;
- tif->tif_decodetile = Fax3Decode2D;
- }
- } else if (needsRefLine) { /* 2d encoding */
- Fax3EncodeState* esp = EncoderState(tif);
+ nruns = needsRefLine ? 2*TIFFroundup(rowpixels,32) : rowpixels;
+
+ dsp->runs = (uint32*) CheckMalloc(tif, 2*nruns+3, sizeof (uint32),
+ "for Group 3/4 run arrays");
+ if (dsp->runs == NULL)
+ return (0);
+ dsp->curruns = dsp->runs;
+ if (needsRefLine)
+ dsp->refruns = dsp->runs + (nruns>>1);
+ else
+ dsp->refruns = NULL;
+ if (is2DEncoding(dsp)) { /* NB: default is 1D routine */
+ tif->tif_decoderow = Fax3Decode2D;
+ tif->tif_decodestrip = Fax3Decode2D;
+ tif->tif_decodetile = Fax3Decode2D;
+ }
+
+ if (needsRefLine) { /* 2d encoding */
+ Fax3CodecState* esp = EncoderState(tif);
/*
* 2d encoding requires a scanline
* buffer for the ``reference line''; the
#define Fax3FlushBits(tif, sp) { \
if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \
(void) TIFFFlushData1(tif); \
- *(tif)->tif_rawcp++ = (sp)->data; \
+ *(tif)->tif_rawcp++ = (tidataval_t) (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++ = data; \
+ *(tif)->tif_rawcp++ = (tidataval_t) data; \
(tif)->tif_rawcc++; \
data = 0, bit = 8; \
}
static void
Fax3PutBits(TIFF* tif, u_int bits, u_int length)
{
- Fax3EncodeState* sp = EncoderState(tif);
- int bit = sp->bit;
+ Fax3CodecState* sp = EncoderState(tif);
+ u_int bit = sp->bit;
int data = sp->data;
_PutBits(tif, bits, length);
static void
putspan(TIFF* tif, int32 span, const tableentry* tab)
{
- Fax3EncodeState* sp = EncoderState(tif);
- int bit = sp->bit;
+ Fax3CodecState* sp = EncoderState(tif);
+ u_int bit = sp->bit;
int data = sp->data;
u_int code, length;
static void
Fax3PutEOL(TIFF* tif)
{
- Fax3EncodeState* sp = EncoderState(tif);
- int bit = sp->bit;
+ Fax3CodecState* sp = EncoderState(tif);
+ u_int bit = sp->bit;
int data = sp->data;
- u_int code, length;
+ u_int code, length, tparm;
if (sp->b.groupoptions & GROUP3OPT_FILLBITS) {
/*
else
align = sp->bit - align;
code = 0;
- _PutBits(tif, 0, align);
+ tparm=align;
+ _PutBits(tif, 0, tparm);
}
}
code = EOL, length = 12;
static int
Fax3PreEncode(TIFF* tif, tsample_t s)
{
- Fax3EncodeState* sp = EncoderState(tif);
+ Fax3CodecState* sp = EncoderState(tif);
(void) s;
assert(sp != NULL);
static int
Fax3Encode1DRow(TIFF* tif, u_char* bp, uint32 bits)
{
- Fax3EncodeState* sp = EncoderState(tif);
- int32 bs = 0, span;
+ Fax3CodecState* sp = EncoderState(tif);
+ int32 span;
+ uint32 bs = 0;
for (;;) {
span = find0span(bp, bs, bits); /* white span */
Fax3Encode2DRow(TIFF* tif, u_char* bp, u_char* rp, uint32 bits)
{
#define PIXEL(buf,ix) ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
- int32 a0 = 0;
- int32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
- int32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
- int32 a2, b2;
+ uint32 a0 = 0;
+ uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
+ uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
+ uint32 a2, b2;
for (;;) {
b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
static int
Fax3Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
{
- Fax3EncodeState* sp = EncoderState(tif);
+ Fax3CodecState* sp = EncoderState(tif);
(void) s;
while ((long)cc > 0) {
}
bp += sp->b.rowbytes;
cc -= sp->b.rowbytes;
- if (cc != 0)
- tif->tif_row++;
}
return (1);
}
static int
Fax3PostEncode(TIFF* tif)
{
- Fax3EncodeState* sp = EncoderState(tif);
+ Fax3CodecState* sp = EncoderState(tif);
if (sp->bit != 8)
Fax3FlushBits(tif, sp);
Fax3Close(TIFF* tif)
{
if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) {
- Fax3EncodeState* sp = EncoderState(tif);
+ Fax3CodecState* sp = EncoderState(tif);
u_int code = EOL;
u_int length = 12;
int i;
Fax3Cleanup(TIFF* tif)
{
if (tif->tif_data) {
- if (tif->tif_mode == O_RDONLY) {
- Fax3DecodeState* sp = DecoderState(tif);
- if (sp->runs)
- _TIFFfree(sp->runs);
- } else {
- Fax3EncodeState* sp = EncoderState(tif);
- if (sp->refline)
- _TIFFfree(sp->refline);
- }
+ Fax3CodecState* sp = DecoderState(tif);
+
+ if (sp->runs)
+ _TIFFfree(sp->runs);
+ if (sp->refline)
+ _TIFFfree(sp->refline);
+
if (Fax3State(tif)->subaddress)
_TIFFfree(Fax3State(tif)->subaddress);
_TIFFfree(tif->tif_data);
sp->mode = va_arg(ap, int);
return (1); /* NB: pseudo tag */
case TIFFTAG_FAXFILLFUNC:
- if (tif->tif_mode == O_RDONLY)
- DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc);
+ DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc);
return (1); /* NB: pseudo tag */
case TIFFTAG_GROUP3OPTIONS:
case TIFFTAG_GROUP4OPTIONS:
*va_arg(ap, int*) = sp->mode;
break;
case TIFFTAG_FAXFILLFUNC:
- if (tif->tif_mode == O_RDONLY)
- *va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill;
+ *va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill;
break;
case TIFFTAG_GROUP3OPTIONS:
case TIFFTAG_GROUP4OPTIONS:
/*
* Allocate state block so tag methods have storage to record values.
*/
- if (tif->tif_mode == O_RDONLY)
- tif->tif_data = _TIFFmalloc(sizeof (Fax3DecodeState));
- else
- tif->tif_data = _TIFFmalloc(sizeof (Fax3EncodeState));
+ tif->tif_data = (tidata_t)
+ _TIFFmalloc(sizeof (Fax3CodecState));
+
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->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 */
+ tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */
sp->groupoptions = 0;
sp->recvparams = 0;
sp->subaddress = NULL;
- if (tif->tif_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;
+ 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.
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);
static int
Fax4Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
{
- Fax3EncodeState *sp = EncoderState(tif);
+ Fax3CodecState *sp = EncoderState(tif);
(void) s;
while ((long)cc > 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 int
Fax4PostEncode(TIFF* tif)
{
- Fax3EncodeState *sp = EncoderState(tif);
+ Fax3CodecState *sp = EncoderState(tif);
/* terminate strip w/ EOFB */
Fax3PutBits(tif, EOL, 12);
}
buf += sp->b.rowbytes;
occ -= sp->b.rowbytes;
- if (occ != 0)
- tif->tif_row++;
continue;
EOFRLE: /* premature EOF */
(*sp->fill)(buf, thisrun, pa, lastx);