[gs-cvs] rev 7491 - trunk/gs/src

lpd at ghostscript.com lpd at ghostscript.com
Mon Dec 11 09:30:54 PST 2006


Author: lpd
Date: 2006-12-11 09:30:53 -0800 (Mon, 11 Dec 2006)
New Revision: 7491

Modified:
   trunk/gs/src/spngp.c
Log:
Fixes bug: the PNG predictor filters produced incorrect data for the last
pixel of each row.  (The encoder and decoder had matching bugs, so
encode+decode produced the correct result!)  Fixes a diff in PS3 CET
23-12U-1.


Modified: trunk/gs/src/spngp.c
===================================================================
--- trunk/gs/src/spngp.c	2006-12-11 04:48:55 UTC (rev 7490)
+++ trunk/gs/src/spngp.c	2006-12-11 17:30:53 UTC (rev 7491)
@@ -113,8 +113,10 @@
  * Process a partial buffer.  We pass in current and previous pointers
  * to both the current and preceding scan line.  Note that dprev is
  * p - bpp for encoding, q - bpp for decoding; similarly, the 'up' row
- * is the raw data for encoding, the filtered data for decoding.
+ * is the raw data for encoding, the filtered (encoded) data for decoding.
  * Note also that the case_index cannot be cOptimum.
+ *
+ * Uses ss->case_index; uses and updates ss->row_left, pr->ptr, pw->ptr.
  */
 private int
 paeth_predictor(int a, int b, int c)
@@ -207,6 +209,9 @@
  *        of the current input row.
  *      prev_row[P .. N + B - 1] contain bytes P - B .. N - 1
  *        of the previous input row.
+ * We must handle the edges of each row specially, by clearing ss->prev at
+ * the beginning of each row, and copying trailing bytes from ss->prev (and
+ * possibly the input) to prev_row at the end of each row.
  */
 private int
 optimum_predictor(const stream_state * st, const stream_cursor_read * pr)
@@ -253,10 +258,15 @@
 
 	    /* Process bytes whose predecessors are in prev. */
 	    s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
+	    if (ss->row_left == 0) {
+		if (ss->prev_row) {
+		    memcpy(up - bpp, ss->prev, bpp);
+		    memcpy(up, pr->ptr - (n - 1), n);
+		}
+		continue;
+	    }
 	    if (ss->prev_row)
 		memcpy(up - bpp, ss->prev, n);
-	    if (ss->row_left == 0)
-		continue;
 	    if (n < bpp) {
 		/*
 		 * We didn't have both enough input data and enough output
@@ -298,6 +308,9 @@
  *        of the current output row.
  *      prev_row[P .. N + B - 1] contain bytes P - B .. N - 1
  *        of the previous output row.
+ * We must handle the edges of each row specially, by clearing ss->prev at
+ * the beginning of each row, and copying trailing bytes from ss->prev (and
+ * possibly the output) to prev_row at the end of each row.
  */
 private int
 s_PNGPD_process(stream_state * st, stream_cursor_read * pr,
@@ -335,10 +348,15 @@
 
 	    /* Process bytes whose predecessors are in prev. */
 	    s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
+	    if (ss->row_left == 0) {
+		if (ss->prev_row) {
+		    memcpy(up - bpp, ss->prev, bpp);
+		    memcpy(up, pw->ptr - (n - 1), n);
+		}
+		continue;
+	    }
 	    if (ss->prev_row)
 		memcpy(up - bpp, ss->prev, n);
-	    if (ss->row_left == 0)
-		continue;
 	    if (n < bpp) {
 		/*
 		 * We didn't have both enough input data and enough output



More information about the gs-cvs mailing list