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

leonardo at ghostscript.com leonardo at ghostscript.com
Fri Feb 1 14:05:51 PST 2008


Author: leonardo
Date: 2008-02-01 14:05:51 -0800 (Fri, 01 Feb 2008)
New Revision: 8515

Modified:
   trunk/gs/src/siscale.c
Log:
Fix (graphics) : Interpolated images were shifed in a half of source pixel.

DETAILS :

Bug 687039 "Interpolated images looks strange on Win32 display device".

1. The old code maps the center of the [0,0]th source pixel
   to the output image origin. However Adobe maps 
   the source pixel's corner to the output origin.
   This patch compensates the shift when computing the
   filter kernel position - see '0.5' when computing 'center'.

2. When the filter kernel scans partially outside the source image,
   the math requires to extrapolate source data somenow
   to fill the kernel. However the old code performs some strange
   computation, which we're not sure what for.
   It looks as a rudiment of wrapping the source image
   like a thorus. Well, it's an useful math for periodic patterns,
   but not for single images. Since we never apply siscale.c to 
   patterns, we replace this code portion with a simpler one,
   which duplicates pixels at image boundaries.
   See attachment to the bug to prove that Adobe does so.

EXPECTED DIFFERENCES :

progression :
"148-11.ps" 

Minor difference (a half pixel shift) :
"289-01.ps" 
"A-12-3480-0109-5.pdf" 
"B-12-3077-1831-7-001.pdf" 
"C-12-2706-0239-9-001.pdf" 
"D-12-2025-9478-9.pdf" 
"E-12-1866-0406-7.pdf" 
"FIG3.eps" 

Well I could compensate the shift for zooming only,
but don't want an assymmetry between scaling up and scaling down.


Modified: trunk/gs/src/siscale.c
===================================================================
--- trunk/gs/src/siscale.c	2008-01-31 22:20:32 UTC (rev 8514)
+++ trunk/gs/src/siscale.c	2008-02-01 22:05:51 UTC (rev 8515)
@@ -195,6 +195,7 @@
     npixels = (int)(WidthIn * 2 + 1);
 
     for (i = 0; i < size; ++i) {
+#if 0
 	double center = (input_index + i) / scale;
 	int left = (int)ceil(center - WidthIn);
 	int right = (int)floor(center + WidthIn);
@@ -219,6 +220,14 @@
 	(right >= limit ? limit - 1 : right);
 	int first_pixel = min(lmin, rmin);
 	int last_pixel = max(lmax, rmax);
+#else
+	double center = (input_index + i) / scale - 0.5;
+	int left = (int)ceil(center - WidthIn);
+	int right = (int)floor(center + WidthIn);
+#define clamp_pixel(j) (j < 0 ? 0 : j >= limit ? limit - 1 : j)
+	int first_pixel = clamp_pixel(left);
+	int last_pixel = clamp_pixel(right);
+#endif
 	CONTRIB *p;
 
 	if (last_pixel > last_index)



More information about the gs-cvs mailing list