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

leonardo at ghostscript.com leonardo at ghostscript.com
Sun Feb 24 01:21:54 PST 2008


Author: leonardo
Date: 2008-02-24 01:21:54 -0800 (Sun, 24 Feb 2008)
New Revision: 8544

Modified:
   trunk/gs/src/siscale.c
Log:
Fix (images) : Improve coordinate precision when scaling an image (continued 8).

DETAILS :

Ghostscript Bug 687345 "Image interpolation problem at a band boundary"
Ghostscript Bug 689686 "siscale.c contrast degradation"

Accurately compute pixel center coordinates when applying the interpolation filter.
See comment in code. When scale=1, the offsets mutually eliminate.
Also the old code missed a bit when computing center_denom/2 in integers.

EXPECTED DIFFERENCES :

Minor difference  : a shift of an image in half pixel :
"148-11.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" 


Modified: trunk/gs/src/siscale.c
===================================================================
--- trunk/gs/src/siscale.c	2008-02-24 03:37:03 UTC (rev 8543)
+++ trunk/gs/src/siscale.c	2008-02-24 09:21:54 UTC (rev 8544)
@@ -206,19 +206,21 @@
 	/* Here we need :
 	   double scale = (double)dst_size / src_size;
 	   float dst_offset_fraction = floor(dst_offset) - dst_offset;
-	   double center = (starting_output_index  + i + dst_offset_fraction) / scale - 0.5;
+	   double center = (starting_output_index  + i + dst_offset_fraction + 0.5) / scale - 0.5;
 	   int left = (int)ceil(center - WidthIn);
 	   int right = (int)floor(center + WidthIn);
 	   We can't compute 'right' in floats because float arithmetics is not associative.
 	   In older versions tt caused a 1 pixel bias of image bands due to 
-	   rounding direction appears to depend on src_y_offset. So compute in rartionals.
+	   rounding direction appears to depend on src_y_offset. So compute in rationals.
+	   Since pixel center fall to half integers, we subtract 0.5 
+	   in the image space and add 0.5 in the device space.
 	 */
 	int dst_y_offset_fraction_num = (int)((int64_t)src_y_offset * dst_size % src_size) * 2 <= src_size
 			? -(int)((int64_t)src_y_offset * dst_size % src_size)
 			: src_size - (int)((int64_t)src_y_offset * dst_size % src_size);
-	int center_denom = dst_size; 
-	int64_t center_num = /* center * center_denom = */ 
-	    (starting_output_index  + i) * src_size + dst_y_offset_fraction_num - (center_denom / 2);
+	int center_denom = dst_size * 2; 
+	int64_t center_num = /* center * center_denom * 2 = */ 
+	    (starting_output_index  + i) * src_size * 2 + src_size + dst_y_offset_fraction_num * 2 - dst_size;
 	int left = (int)ceil((center_num - WidthIn * center_denom) / center_denom);
 	int right = (int)floor((center_num + WidthIn * center_denom) / center_denom);
 	double center = (double)center_num / center_denom;



More information about the gs-cvs mailing list