]> git.saurik.com Git - wxWidgets.git/blobdiff - src/tiff/tif_fax3.c
fix wxStringOutputStream::Write() in Unicode build when the output overlaps a boundar...
[wxWidgets.git] / src / tiff / tif_fax3.c
index 4be62aedea671a4ce53fe80bc585a17c1a5d0797..9474e977c79a974a503f520b8e659a60596d6e1b 100644 (file)
 #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 */
@@ -71,8 +66,11 @@ typedef struct {
 } 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 */
@@ -81,19 +79,15 @@ typedef struct {
        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)
@@ -109,7 +103,7 @@ typedef struct {
  */
 #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 */           \
@@ -153,7 +147,7 @@ typedef struct {
 static int
 Fax3PreDecode(TIFF* tif, tsample_t s)
 {
-       Fax3DecodeState* sp = DecoderState(tif);
+       Fax3CodecState* sp = DecoderState(tif);
 
        (void) s;
        assert(sp != NULL);
@@ -170,7 +164,7 @@ Fax3PreDecode(TIFF* tif, tsample_t s)
        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);
@@ -244,8 +238,6 @@ 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;
-               if (occ != 0)
-                       tif->tif_row++;
                continue;
        EOF1D:                          /* premature EOF */
                CLEANUP_RUNS();
@@ -298,8 +290,6 @@ 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;
-               if (occ != 0)
-                       tif->tif_row++;
                continue;
        EOF2D:                          /* premature EOF */
                CLEANUP_RUNS();
@@ -319,7 +309,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 defined(__alpha) || _MIPS_SZLONG == 64
+#if defined(__alpha) || (defined(_MIPS_SZLONG) && _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;\
@@ -372,8 +362,8 @@ _TIFFFax3fillruns(u_char* buf, uint32* runs, uint32* erun, uint32 lastx)
        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;
@@ -400,18 +390,14 @@ _TIFFFax3fillruns(u_char* buf, uint32* runs, uint32* erun, uint32 lastx)
                        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);
@@ -439,12 +425,8 @@ _TIFFFax3fillruns(u_char* buf, uint32* runs, uint32* erun, uint32 lastx)
                        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];
@@ -455,6 +437,21 @@ _TIFFFax3fillruns(u_char* buf, uint32* runs, uint32* erun, uint32 lastx)
 #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
@@ -469,6 +466,8 @@ Fax3SetupState(TIFF* tif)
        Fax3BaseState* sp = Fax3State(tif);
        long rowbytes, rowpixels;
        int needsRefLine;
+       Fax3CodecState* dsp = DecoderState(tif);
+       uint32 nruns;
 
        if (td->td_bitspersample != 1) {
                TIFFError(tif->tif_name,
@@ -494,30 +493,26 @@ Fax3SetupState(TIFF* tif)
            (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
@@ -544,14 +539,14 @@ Fax3SetupState(TIFF* tif)
 #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;                                      \
 }
@@ -577,8 +572,8 @@ static const int _msbmask[9] =
 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);
@@ -612,8 +607,8 @@ Fax3PutBits(TIFF* tif, u_int bits, u_int 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;
 
@@ -655,10 +650,10 @@ putspan(TIFF* tif, int32 span, const tableentry* tab)
 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) {
                /*
@@ -673,7 +668,8 @@ Fax3PutEOL(TIFF* tif)
                        else
                                align = sp->bit - align;
                        code = 0;
-                       _PutBits(tif, 0, align);
+                       tparm=align; 
+                       _PutBits(tif, 0, tparm);
                }
        }
        code = EOL, length = 12;
@@ -691,7 +687,7 @@ Fax3PutEOL(TIFF* tif)
 static int
 Fax3PreEncode(TIFF* tif, tsample_t s)
 {
-       Fax3EncodeState* sp = EncoderState(tif);
+       Fax3CodecState* sp = EncoderState(tif);
 
        (void) s;
        assert(sp != NULL);
@@ -919,8 +915,9 @@ find1span(u_char* bp, int32 bs, int32 be)
 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 */
@@ -966,10 +963,10 @@ static int
 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));
@@ -1010,7 +1007,7 @@ Fax3Encode2DRow(TIFF* tif, u_char* bp, u_char* rp, uint32 bits)
 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) {
@@ -1037,8 +1034,6 @@ Fax3Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
                }
                bp += sp->b.rowbytes;
                cc -= sp->b.rowbytes;
-               if (cc != 0)
-                       tif->tif_row++;
        }
        return (1);
 }
@@ -1046,7 +1041,7 @@ Fax3Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
 static int
 Fax3PostEncode(TIFF* tif)
 {
-       Fax3EncodeState* sp = EncoderState(tif);
+       Fax3CodecState* sp = EncoderState(tif);
 
        if (sp->bit != 8)
                Fax3FlushBits(tif, sp);
@@ -1057,7 +1052,7 @@ static void
 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;
@@ -1074,15 +1069,13 @@ static void
 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);
@@ -1141,8 +1134,7 @@ Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap)
                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:
@@ -1184,8 +1176,7 @@ Fax3VGetField(TIFF* tif, ttag_t tag, va_list ap)
                *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:
@@ -1279,37 +1270,36 @@ InitCCITTFax3(TIFF* tif)
        /*
         * 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.
@@ -1373,15 +1363,22 @@ Fax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
                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);
@@ -1397,7 +1394,7 @@ Fax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
 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) {
@@ -1406,8 +1403,6 @@ Fax4Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
                _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
                bp += sp->b.rowbytes;
                cc -= sp->b.rowbytes;
-               if (cc != 0)
-                       tif->tif_row++;
        }
        return (1);
 }
@@ -1415,7 +1410,7 @@ Fax4Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
 static int
 Fax4PostEncode(TIFF* tif)
 {
-       Fax3EncodeState *sp = EncoderState(tif);
+       Fax3CodecState *sp = EncoderState(tif);
 
        /* terminate strip w/ EOFB */
        Fax3PutBits(tif, EOL, 12);
@@ -1488,8 +1483,6 @@ Fax3DecodeRLE(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
                }
                buf += sp->b.rowbytes;
                occ -= sp->b.rowbytes;
-               if (occ != 0)
-                       tif->tif_row++;
                continue;
        EOFRLE:                         /* premature EOF */
                (*sp->fill)(buf, thisrun, pa, lastx);