summaryrefslogtreecommitdiff
path: root/base/siscale.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2018-03-08 13:21:54 +0000
committerRobin Watts <robin.watts@artifex.com>2018-03-08 13:25:32 +0000
commitd68b62d7567f20f0f269d096b899bd2409967980 (patch)
tree34f658756b359758c63742d526f739823f3240ea /base/siscale.c
parent676dfb338d296aa86630662714fce5f058e31b8f (diff)
downloadghostpdl-d68b62d7567f20f0f269d096b899bd2409967980.tar.gz
Avoid total image dropout in interplated rescales.
Tests show that the following command causes images to disappear: gxps -o out.ppm -sDEVICE=ppmraw -72 tests_private/xps/xpsfts-a4/fts_27xx.xps This is because we scale a 1600 wide image down to 27 pixels across. As such the weights for each individual pixel round to zero, and we get nothing displayed. Adjust for this by still calculating weights as doubles, and carrying the error across the line. This keeps the total sum of the differences correct.
Diffstat (limited to 'base/siscale.c')
-rw-r--r--base/siscale.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/base/siscale.c b/base/siscale.c
index e173eba74..6520ae3b7 100644
--- a/base/siscale.c
+++ b/base/siscale.c
@@ -262,29 +262,37 @@ calculate_contrib(
p[j].weight = 0;
if (squeeze) {
double sum = 0;
+ double e = 0;
for (j = left; j <= right; ++j)
sum += fproc((center - j) / fscale) / fscale;
for (j = left; j <= right; ++j) {
double weight = fproc((center - j) / fscale) / fscale / sum;
int n = clamp_pixel(j);
int k = n - first_pixel;
+ int ie;
- p[k].weight +=
- (int)((weight * rescale_factor) * CONTRIB_SCALE + 0.5);
+ e += (weight * rescale_factor) * CONTRIB_SCALE;
+ ie = (int)(e + 0.5);
+ p[k].weight += ie;
+ e -= ie;
if_debug2('w', " %d %f", k, (float)p[k].weight);
}
} else {
double sum = 0;
+ double e = 0;
for (j = left; j <= right; ++j)
sum += fproc(center - j);
for (j = left; j <= right; ++j) {
double weight = fproc(center - j) / sum;
int n = clamp_pixel(j);
int k = n - first_pixel;
+ int ie;
- p[k].weight +=
- (int)((weight * rescale_factor) * CONTRIB_SCALE + 0.5);
+ e += (weight * rescale_factor) * CONTRIB_SCALE;
+ ie = (int)(e + 0.5);
+ p[k].weight += ie;
+ e -= ie;
if_debug2('w', " %d %f", k, (float)p[k].weight);
}
}