Author: leonardo
Date: 2008-03-22 14:55:00 -0700 (Sat, 22 Mar 2008)
New Revision: 8605

Modified:
   trunk/gs/src/gdevddrw.c
   trunk/gs/src/gdevmr8n.c
   trunk/gs/src/gxclrect.c
   trunk/gs/src/lib.mak
Log:
Fix (clist writer) : Smaller tiles for strip_copy_rop.

DETAILS :

Bug 689588 "Unexpected InternalOverflow in ReadImage".

When strip_copy_rop recieves a big tile, it is being subdivided into line tiles
to fit into the clist buffer. However the line tile can be too big as well.
The new code narrows the line tile with the size of the rectangle to be painted.
For details see comments added into gxclrect.c .

Minor change (gdevddrw.c, gdevmr8n.c) Added visual trace commands for easier debugging.

EXPECTED DIFFERENCES :

None.      


Modified: trunk/gs/src/gdevddrw.c
===================================================================
--- trunk/gs/src/gdevddrw.c	2008-03-21 05:07:53 UTC (rev 8604)
+++ trunk/gs/src/gdevddrw.c	2008-03-22 21:55:00 UTC (rev 8605)
@@ -928,7 +928,16 @@
 		      const byte ** plane_data,
 		      int data_x, uint raster, int height)
 {
-    return gx_image_data(info, plane_data, data_x, raster, height);
+    int code;
+
+    vd_get_dc('i');
+    vd_set_shift(0, 0);
+    vd_set_scale(0.01);
+    vd_set_origin(0, 0);
+    /* vd_erase(RGB(192, 192, 192)); */
+    code = gx_image_data(info, plane_data, data_x, raster, height);
+    vd_release_dc;
+    return code;
 }
 
 int

Modified: trunk/gs/src/gdevmr8n.c
===================================================================
--- trunk/gs/src/gdevmr8n.c	2008-03-21 05:07:53 UTC (rev 8604)
+++ trunk/gs/src/gdevmr8n.c	2008-03-22 21:55:00 UTC (rev 8605)
@@ -24,6 +24,7 @@
 #include "gxdevrop.h"
 #include "gdevmem.h"
 #include "gdevmrop.h"
+#include "vdtrace.h"
 
 /*
  * NOTE: The 16- and 32-bit cases aren't implemented: they just fall back to
@@ -54,7 +55,7 @@
     gx_color_index const_texture = gx_no_color_index;
     uint draster = mdev->raster;
     int line_count;
-    byte *drow;
+    byte *drow, *base;
     int depth = dev->color_info.depth;
     int bpp = depth >> 3;	/* bytes per pixel, 1 or 3 */
     gx_color_index all_ones = ((gx_color_index) 1 << depth) - 1;
@@ -140,7 +141,8 @@
 
     /* Set up transfer parameters. */
     line_count = height;
-    drow = scan_line_base(mdev, y) + x * bpp;
+    base = scan_line_base(mdev, y);
+    drow = base + x * bpp;
 
     /*
      * There are 18 cases depending on whether each of the source and
@@ -192,11 +194,15 @@
 		if (bpp == 1)
 /**** 8-bit destination ****/
 		    for (; left > 0; ++dptr, --left) {
+			vd_pixel(int2fixed((dptr - base) % draster), 
+				 int2fixed((dptr - base) / draster + y), const_texture);
 			rop_body_8((byte)const_source, (byte)const_texture);
 		    }
 		else
 /**** 24-bit destination ****/
 		    for (; left > 0; dptr += 3, --left) {
+			vd_pixel(int2fixed((dptr - base) % draster / 3), 
+				 int2fixed((dptr - base) / draster + y), const_texture);
 			rop_body_24(const_source, const_texture);
 		    }
 	    }
@@ -217,6 +223,8 @@
 			for (; left > 0; ++dptr, ++sx, --left) {
 			    byte s_pixel = cbit8(srow, sx, scolors);
 
+			    vd_pixel(int2fixed((dptr - base) % draster), 
+				 int2fixed((dptr - base) / draster + y), const_texture);
 			    rop_body_8(s_pixel, (byte)const_texture);
 			}
 		    else
@@ -224,6 +232,8 @@
 			for (; left > 0; dptr += 3, ++sx, --left) {
 			    bits32 s_pixel = cbit24(srow, sx, scolors);
 
+			    vd_pixel(int2fixed((dptr - base) % draster / 3), 
+				 int2fixed((dptr - base) / draster + y), const_texture);
 			    rop_body_24(s_pixel, const_texture);
 			}
 		} else if (bpp == 1) {
@@ -233,6 +243,8 @@
 		    for (; left > 0; ++dptr, ++sptr, --left) {
 			byte s_pixel = *sptr;
 
+			vd_pixel(int2fixed((dptr - base) % draster), 
+				 int2fixed((dptr - base) / draster + y), const_texture);
 			rop_body_8(s_pixel, (byte)const_texture);
 		    }
 		} else {
@@ -242,6 +254,8 @@
 		    for (; left > 0; dptr += 3, sptr += 3, --left) {
 			bits32 s_pixel = get24(sptr);
 
+			vd_pixel(int2fixed((dptr - base) % draster / 3), 
+				 int2fixed((dptr - base) / draster + y), const_texture);
 			rop_body_24(s_pixel, const_texture);
 		    }
 		}
@@ -271,6 +285,8 @@
 			for (; left > 0; ++dptr, ++tx, --left) {
 			    byte t_pixel = cbit8(tptr, tx, tcolors);
 
+			    vd_pixel(int2fixed((dptr - base) % draster), 
+				 int2fixed((dptr - base) / draster + y), t_pixel);
 			    rop_body_8((byte)const_source, t_pixel);
 			}
 		    else
@@ -278,6 +294,8 @@
 			for (; left > 0; dptr += 3, ++tx, --left) {
 			    bits32 t_pixel = cbit24(tptr, tx, tcolors);
 
+			    vd_pixel(int2fixed((dptr - base) % draster / 3), 
+				 int2fixed((dptr - base) / draster + y), t_pixel);
 			    rop_body_24(const_source, t_pixel);
 			}
 		} else if (bpp == 1) {
@@ -286,6 +304,8 @@
 		    for (; left > 0; ++dptr, ++tptr, --left) {
 			byte t_pixel = *tptr;
 
+			vd_pixel(int2fixed((dptr - base) % draster), 
+				 int2fixed((dptr - base) / draster + y), t_pixel);
 			rop_body_8((byte)const_source, t_pixel);
 		    }
 		} else {
@@ -294,6 +314,8 @@
 		    for (; left > 0; dptr += 3, tptr += 3, --left) {
 			bits32 t_pixel = get24(tptr);
 
+			vd_pixel(int2fixed((dptr - base) % draster / 3), 
+				 int2fixed((dptr - base) / draster + y), t_pixel);
 			rop_body_24(const_source, t_pixel);
 		    }
 		}
@@ -340,6 +362,8 @@
 			byte t_pixel =
 			    (tcolors ? cbit8(tptr, tx, tcolors) : *tptr);
 
+			vd_pixel(int2fixed((dptr - base) % draster), 
+				 int2fixed((dptr - base) / draster + y), t_pixel);
 			rop_body_8(s_pixel, t_pixel);
 		    }
 		} else {
@@ -355,6 +379,8 @@
 			    (tcolors ? cbit24(tptr, tx, tcolors) :
 			     get24(tptr));
 
+			vd_pixel(int2fixed((dptr - base) % draster / 3), 
+				 int2fixed((dptr - base) / draster + y), t_pixel);
 			rop_body_24(s_pixel, t_pixel);
 		    }
 		}

Modified: trunk/gs/src/gxclrect.c
===================================================================
--- trunk/gs/src/gxclrect.c	2008-03-21 05:07:53 UTC (rev 8604)
+++ trunk/gs/src/gxclrect.c	2008-03-22 21:55:00 UTC (rev 8605)
@@ -981,6 +981,9 @@
 			uint rep_height = tiles->rep_height;
 			gs_id ids;
 			gx_strip_bitmap line_tile;
+			int data_shift = 0, phase_shift = 0, raster;
+			int new_phase = phase_x;
+			int tile_space_phase;
 			int iy;
 
 			if (rep_height == 1 ||
@@ -996,16 +999,45 @@
 			line_tile = *tiles;
 			line_tile.size.y = 1;
 			line_tile.rep_height = 1;
+			raster = line_tile.raster;
+			/* The rasterizer assumes tile phase relatively to the rectangle origin,
+			   (see x_offset in gdevmr8n.c), so compute "the tile phase in the tile space" 
+			   with same expression : */
+			tile_space_phase = (rx + phase_x) % tiles->rep_width;
+			if (tile_space_phase + rwidth <= tiles->rep_width) {
+			    /* Narrow the tile to prevent buffer overflow - bug 689588.
+			       Note currently we don't narrow "wrapped" tiles (because bug 689588 doesn't need) :
+			       when tile_space_phase < rep_width && tile_space_phase + rwidth > rep_width, 
+			       each line to be converted into 2 ones.
+			    */
+			    int depth = dev->color_info.depth;
+
+#			    if 0
+			    /* Align bitmap data : */
+   			    data_shift = ((tile_space_phase * depth) >> (log2_align_bitmap_mod + 3)) << log2_align_bitmap_mod;
+#			    else
+   			    data_shift = tile_space_phase * depth / 8; /* No bitmap data alignment because we'll only write it to clist.  */
+#			    endif
+			    phase_shift = data_shift * 8 / depth;
+			    line_tile.rep_width = rwidth + (tile_space_phase - phase_shift);
+			    /* Normally line_tile.raster must account trailing row alignment bytes and 
+			       to be computed as bitmap_raster(line_tile.rep_width * depth); 
+			       but we can't apply it here because the trailing alignment bytes may be absent
+			       due to data_shift. We believe it is not harmful because we just write the data to clist,
+			       and because the bitmap height is 1.
+			       The clist reader must provide the trailing bytes if the rasterizer needs them.
+			     */
+			    line_tile.raster = (line_tile.rep_width * depth + 7) / 8; 
+			    line_tile.size.x = line_tile.rep_width;
+			    line_tile.shift = 0;
+			    new_phase = (tile_space_phase - phase_shift - rx % line_tile.rep_width);
+			    /* Provide a positive phase for clist reader : */
+			    new_phase = (new_phase + line_tile.rep_width) % line_tile.rep_width;
+			}
 			for (iy = 0; iy < re.height; ++iy) {
-			    line_tile.data = tiles->data + line_tile.raster *
-				((re.y + iy + phase_y) % rep_height);
+			    line_tile.data = tiles->data + raster *
+				((re.y + iy + phase_y) % rep_height) + data_shift;
 			    line_tile.id = ids + (iy % rep_height);
-			    /*
-			     * Note that since we're only transferring
-			     * a single scan line, phase_y is irrelevant;
-			     * we may as well use the current tile phase
-			     * so we don't have to write extra commands.
-			     */
 			    ++cdev->driver_call_nesting;
 			    {
 				code = clist_strip_copy_rop(dev,
@@ -1014,7 +1046,7 @@
 					gx_no_bitmap_id, scolors,
 					&line_tile, tcolors,
 					rx, re.y + iy, rwidth, 1,
-					phase_x, re.pcls->tile_phase.y, lop);
+					new_phase, 0, lop);
 			    } 
 			    --cdev->driver_call_nesting;
 			    if (code < 0 && SET_BAND_CODE(code))
@@ -1022,9 +1054,8 @@
 			}
 			continue;
 		    }
-		    if (phase_x != re.pcls->tile_phase.x ||
-			phase_y != re.pcls->tile_phase.y
-			) {
+		    if (((phase_x != re.pcls->tile_phase.x) && (tiles->rep_width > 1)) ||
+			((phase_y != re.pcls->tile_phase.y) && (tiles->rep_height > 1))) {
 			do {
 			    code = cmd_set_tile_phase(cdev, re.pcls, phase_x,
 						      phase_y);

Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak	2008-03-21 05:07:53 UTC (rev 8604)
+++ trunk/gs/src/lib.mak	2008-03-22 21:55:00 UTC (rev 8605)
@@ -1871,7 +1871,7 @@
 $(GLOBJ)gdevmr8n.$(OBJ) : $(GLSRC)gdevmr8n.c $(GXERR) $(memory__h)\
  $(gsbittab_h) $(gsropt_h)\
  $(gxcindex_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxdevrop_h)\
- $(gdevmem_h) $(gdevmrop_h)
+ $(gdevmem_h) $(gdevmrop_h) $(vdtrace_h)
 	$(GLCC) $(GLO_)gdevmr8n.$(OBJ) $(C_) $(GLSRC)gdevmr8n.c
 
 $(GLOBJ)gdevrops.$(OBJ) : $(GLSRC)gdevrops.c $(GXERR)\

_______________________________________________
gs-cvs mailing list
gs-cvs@ghostscript.com
http://www.ghostscript.com/mailman/listinfo/gs-cvs
