X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b47c832e5529dc6c632536b4665a005f0a85aec8..62075bca1f8917a71cb382b53ff3b2a35578e25f:/src/tiff/tif_packbits.c diff --git a/src/tiff/tif_packbits.c b/src/tiff/tif_packbits.c index cf33794065..63a03d14b8 100644 --- a/src/tiff/tif_packbits.c +++ b/src/tiff/tif_packbits.c @@ -109,16 +109,16 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) state = RUN; if (n > 128) { *op++ = (tidata) -127; - *op++ = b; + *op++ = (tidataval_t) b; n -= 128; goto again; } *op++ = (tidataval_t)(-(n-1)); - *op++ = b; + *op++ = (tidataval_t) b; } else { lastliteral = op; *op++ = 0; - *op++ = b; + *op++ = (tidataval_t) b; state = LITERAL; } break; @@ -127,32 +127,32 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) state = LITERAL_RUN; if (n > 128) { *op++ = (tidata) -127; - *op++ = b; + *op++ = (tidataval_t) b; n -= 128; goto again; } *op++ = (tidataval_t)(-(n-1)); /* encode run */ - *op++ = b; + *op++ = (tidataval_t) b; } else { /* extend literal */ if (++(*lastliteral) == 127) state = BASE; - *op++ = b; + *op++ = (tidataval_t) b; } break; case RUN: /* last object was run */ if (n > 1) { if (n > 128) { *op++ = (tidata) -127; - *op++ = b; + *op++ = (tidataval_t) b; n -= 128; goto again; } *op++ = (tidataval_t)(-(n-1)); - *op++ = b; + *op++ = (tidataval_t) b; } else { lastliteral = op; *op++ = 0; - *op++ = b; + *op++ = (tidataval_t) b; state = LITERAL; } break; @@ -188,14 +188,38 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) static int PackBitsEncodeChunk(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) { +#if defined(__hpux) && defined(__LP64__) + tsize_t rowsize = (tsize_t)(unsigned long) tif->tif_data; +#else tsize_t rowsize = (tsize_t) tif->tif_data; +#endif assert(rowsize > 0); + +#ifdef YCBCR_SUPPORT + /* + * YCBCR data isn't really separable into rows, so we + * might as well encode the whole tile/strip as one chunk. + */ + if( tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR ) { +#if defined(__hpux) && defined(__LP64__) + rowsize = (tsize_t)(unsigned long) tif->tif_data; +#else + rowsize = (tsize_t) tif->tif_data; +#endif + } +#endif + while ((long)cc > 0) { - if (PackBitsEncode(tif, bp, rowsize, s) < 0) - return (-1); - bp += rowsize; - cc -= rowsize; + int chunk = rowsize; + + if( cc < chunk ) + chunk = cc; + + if (PackBitsEncode(tif, bp, chunk, s) < 0) + return (-1); + bp += chunk; + cc -= chunk; } return (1); } @@ -222,13 +246,29 @@ PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) if (n < 0) { /* replicate next byte -n+1 times */ if (n == -128) /* nop */ continue; - n = -n + 1; + n = -n + 1; + if( occ < n ) + { + TIFFWarning(tif->tif_name, + "PackBitsDecode: discarding %d bytes " + "to avoid buffer overrun", + n - occ); + n = occ; + } occ -= n; b = *bp++, cc--; while (n-- > 0) - *op++ = b; + *op++ = (tidataval_t) b; } else { /* copy next n+1 bytes literally */ - _TIFFmemcpy(op, bp, ++n); + if (occ < n + 1) + { + TIFFWarning(tif->tif_name, + "PackBitsDecode: discarding %d bytes " + "to avoid buffer overrun", + n - occ + 1); + n = occ - 1; + } + _TIFFmemcpy(op, bp, ++n); op += n; occ -= n; bp += n; cc -= n; } @@ -241,7 +281,6 @@ PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) (long) tif->tif_row); return (0); } - /* check for buffer overruns? */ return (1); }