diff options
author | Robin Watts <robin.watts@artifex.com> | 2018-03-08 13:21:54 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2018-03-08 13:25:32 +0000 |
commit | d68b62d7567f20f0f269d096b899bd2409967980 (patch) | |
tree | 34f658756b359758c63742d526f739823f3240ea /base/siscale.c | |
parent | 676dfb338d296aa86630662714fce5f058e31b8f (diff) | |
download | ghostpdl-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.c | 16 |
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); } } |