#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 */
- 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 */
+ Fax3BaseState b;
+ int data; /* current i/o byte */
+ int bit; /* current i/o bit in byte */
+ enum { G3_1D, G3_2D } 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))
uint32 nruns = needsRefLine ?
2*TIFFroundup(rowpixels,32) : rowpixels;
+#if 0
dsp->runs = (uint32*) _TIFFmalloc(nruns*sizeof (uint16));
+#endif
+ /*
+Problem
+-------
+
+Decoding the file frle_bug.tif causes a crash (such as with tiff2rgba).
+
+In particular the array dsp->runs allocated in Fax3SetupState() is overrun
+by 4-8 bytes. This occurs when Fax3DecodeRLE() processes the first
+scanline. The EXPAND1D() macro advances "pa" to be thisrun+512 (an
+alias for dsp->runs), pointing just beyond the end of the array. Then
+the call to _TIFFFax3fillruns() does an "*erun++ = 0;" which writes beyond
+the end of the array.
+
+In the short term I have modified the dsp->runs allocation to add eight
+extra bytes to the runs buffer; however, I am only doing this because I
+don't understand the algorithm well enough to change it without risking
+more adverse side effects.
+
+Frank Warmerdam (warmerda@home.com)
+
+ */
+
+ dsp->runs = (uint32*) _TIFFmalloc(8+nruns*sizeof (uint32));
+
if (dsp->runs == NULL) {
TIFFError("Fax3SetupState",
"%s: No space for Group 3/4 run arrays",
}
code = EOL, length = 12;
if (is2DEncoding(sp))
+#if defined(__VISAGECPP30__)
+/* VA 3.0 is just plain wierd. */
+ code = (code<<1) | (sp->tag == Fax3EncodeState::G3_1D), length++;
+#else
code = (code<<1) | (sp->tag == G3_1D), length++;
+#endif
_PutBits(tif, code, length);
sp->data = data;
assert(sp != NULL);
sp->bit = 8;
sp->data = 0;
+#if defined(__VISAGECPP30__)
+/* VA 3.0 is just plain wierd. */
+ sp->tag = Fax3EncodeState::G3_1D;
+#else
sp->tag = G3_1D;
+#endif
/*
* This is necessary for Group 4; otherwise it isn't
* needed because the first scanline of each strip ends
if ((sp->b.mode & FAXMODE_NOEOL) == 0)
Fax3PutEOL(tif);
if (is2DEncoding(sp)) {
+#if defined(__VISAGECPP30__)
+/* VA 3.0 is just plain wierd. */
+ if (sp->tag == Fax3EncodeState::G3_1D) {
+#else
if (sp->tag == G3_1D) {
+#endif
if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
return (0);
+#if defined(__VISAGECPP30__)
+/* VA 3.0 is just plain wierd. */
+ sp->tag = Fax3EncodeState::G3_2D;
+#else
sp->tag = G3_2D;
+#endif
} else {
if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
return (0);
sp->k--;
}
if (sp->k == 0) {
+#if defined(__VISAGECPP30__)
+/* VA 3.0 is just plain wierd. */
+ sp->tag = Fax3EncodeState::G3_1D;
+#else
sp->tag = G3_1D;
+#endif
sp->k = sp->maxk-1;
} else
_TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
int i;
if (is2DEncoding(sp))
+#if defined(__VISAGECPP30__)
+/* VA 3.0 is just plain wierd. */
+ code = (code<<1) | (sp->tag == Fax3EncodeState::G3_1D), length++;
+#else
code = (code<<1) | (sp->tag == G3_1D), length++;
+#endif
for (i = 0; i < 6; i++)
Fax3PutBits(tif, code, length);
Fax3FlushBits(tif, sp);
* Allocate state block so tag methods have storage to record values.
*/
if (tif->tif_mode == O_RDONLY)
+#if defined(__VISAGECPP__)
+ tif->tif_data = (tidata_t)_TIFFmalloc(sizeof (Fax3DecodeState));
+ else
+ tif->tif_data = (tidata_t)_TIFFmalloc(sizeof (Fax3EncodeState));
+#else
tif->tif_data = _TIFFmalloc(sizeof (Fax3DecodeState));
else
tif->tif_data = _TIFFmalloc(sizeof (Fax3EncodeState));
+#endif
if (tif->tif_data == NULL) {
TIFFError("TIFFInitCCITTFax3",
"%s: No space for state block", tif->tif_name);