]> git.saurik.com Git - wxWidgets.git/blobdiff - src/tiff/tif_packbits.c
Fix scrolling bug where client size was reported wrong
[wxWidgets.git] / src / tiff / tif_packbits.c
index cf337940653347b05fd2a9ce320937c7e710fd28..63a03d14b8df36a7e98f3b40834cfc45db93901b 100644 (file)
@@ -109,16 +109,16 @@ PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
                                state = RUN;
                                if (n > 128) {
                                        *op++ = (tidata) -127;
                                state = RUN;
                                if (n > 128) {
                                        *op++ = (tidata) -127;
-                                       *op++ = b;
+                                       *op++ = (tidataval_t) b;
                                        n -= 128;
                                        goto again;
                                }
                                *op++ = (tidataval_t)(-(n-1));
                                        n -= 128;
                                        goto again;
                                }
                                *op++ = (tidataval_t)(-(n-1));
-                               *op++ = b;
+                               *op++ = (tidataval_t) b;
                        } else {
                                lastliteral = op;
                                *op++ = 0;
                        } else {
                                lastliteral = op;
                                *op++ = 0;
-                               *op++ = b;
+                               *op++ = (tidataval_t) b;
                                state = LITERAL;
                        }
                        break;
                                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;
                                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 */
                                        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;
                        } 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;
                        }
                        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));
                                        n -= 128;
                                        goto again;
                                }
                                *op++ = (tidataval_t)(-(n-1));
-                               *op++ = b;
+                               *op++ = (tidataval_t) b;
                        } else {
                                lastliteral = op;
                                *op++ = 0;
                        } else {
                                lastliteral = op;
                                *op++ = 0;
-                               *op++ = b;
+                               *op++ = (tidataval_t) b;
                                state = LITERAL;
                        }
                        break;
                                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)
 {
 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;
        tsize_t rowsize = (tsize_t) tif->tif_data;
+#endif
 
        assert(rowsize > 0);
 
        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) {
        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);
 }
        }
        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;
                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)
                        occ -= n;
                        b = *bp++, cc--;
                        while (n-- > 0)
-                               *op++ = b;
+                               *op++ = (tidataval_t) b;
                } else {                /* copy next n+1 bytes literally */
                } 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;
                }
                        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);
        }
                    (long) tif->tif_row);
                return (0);
        }
-       /* check for buffer overruns? */
        return (1);
 }
 
        return (1);
 }