[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