The distiller parameter documentation for ColorImageDownsampleThreshold isn't particularly well worded, but my understanding is that if ColorImageResolution=150 and ColorImageDownsampleThreshold=1.5, then any images with resolution greater than 150*1.5=225dpi will be downsampled to 150dpi. This is consistent with the user interface of Distiller. I've found that an image with resolution of 300dpi is downsampled to 150dpi as expected when using threshold 1.0 to 1.9. An image with a fractionally smaller resolution is not downsampled. Attached is an example PostScript file and a script to process it. Change the "scale" line in the PostScript file to get different results. With "72 36 scale", the image is downsampled. With "72.00001 36 scale", the image is NOT downsampled.
Created attachment 597 [details] PostScript file to draw image at about 300dpi
Created attachment 598 [details] Script to run ghostscript
Customer #1110 has reported that they've been experiencing this bug for a while but not gotten around to reporting it. Customer claims that when making PDF, no scaling is done unless the image's original resolution is an integer multiple of the desired resolution.
Russell, I guess you assume the bigger scale the bigger image resolution. At least your example : %72.0 36 scale % good 72.00001 36 scale % bad looks so. IMO GS assumes vise versa : the bigger scale, the SMALLER image dots per inch. See gdevpsdi.c ln 319. Does this help to your problem ? Thnx. Another related thing is gdevpsdi.c ln 205. It truncates the factor to integers. I guess that you and the Customer #1110 want no truncation. IMO it is safe to change. Do you think it would be enough ? Thnx.
Igor, No, I assume that larger scale factor = smaller dpi, since the width of the image in pixels has not changed. That is, the "72 scale" gives 300dpi and the "72.0001 scale" gives 299.999dpi. At gdevpsdi.c:205, truncating "factor" is wrong. This would prevent a 299.999 dpi image from being downsampled since factor = (int)(299.99/150) = 1, which is less than the default 1.5 downsample threshold. Changing just that line isn't sufficient to fix the problem. Line 223 also needs to be changed to a float type, and so it continues. We do need to downsample by non-integer factors. The current behaviour differs from Distiller, which with a downsample threshold of 1.5 and a downsample resolution of 150dpi, will downsample the 299.999 dpi image to 150dpi.
Russell, I guess you've got a technology for testing this feature, so could you please patch it ? If you want, assign this bug to yourself.
I'm not sure whether or not pdfwrite should ever perform non-integer downsampling, but if we do need to perform this, I will soon commit an image filter that supports non-integer scaling. This is an averaging filter that is intended to match Adobe Reader's image smoothing. When this is complete, it will be a working version of the siinterp.c module (currently it does nothing -- a pass through filter).
Distiller does downsample by non-integer fractions. With the threshold set to 225dpi (1.5), and an input image resolution of 250dpi (86.4 43.2 scale in example file), distiller downsamples the width from 300pixels down to 180pixels, a ratio of 150dpi/250dpi. The original problem file was actually doing something like 299.9999dpi, so at least rounding to 300dpi instead of truncating to 299dpi would give a better result until the downsampling algorithmn can be updated.
Russell, When you say "an input image resolution of 250dpi", I'm not sure what does this mean exactly : Is this just an inverse of the image matrix ? How do you convert the inverse matrix into a single number ? Since you're experimenting with this problem, maybe you know (or can get) an answer for the following key question : If an image to be downsampled, what scale to be used ? In other words, how to compute the scale from the image size, DownsampleTrheshold and ImageResolution ?
Igor, For the testing with 300dpi, I used 72 36 scale 300 150 8 [300 0 0 150 0 0] {proc} image That is, it spreads 300 pixels over 72 points. For the 250dpi test I used 86.4 43.2 scale 300 150 8 [300 0 0 150 0 0] {proc} image So the resolution of the image is 72/86.4 * 300 = 250dpi. This gets messy if horizontal and vertical resolutions differ. Some checks with Distiller 6 show that if either horizontal or vertical resolution are below the threshold, do not downsample. If (hdpi > threshold) and (vdpi > threshold), downsample so that the new hdpi and vdpi are the desired resolution, even if this requires different horizontal and vertical scale factors. So to determine the scaling factor, I would suggest: Take image size and matrix and calculate image_hdpi and image_vdpi. (Don't even think about the case when the image is slanted :-) Take the smaller of the two as image_dpi. If image_dpi > ImageResolution*ImageDownsampleThreshold then downsample image. Horizontal scale factor is ImageResolution / image_hdpi. Vertical scale factor is ImageResolution / image_vdpi.
Russell, Thank you for the helpful analyzis. However there is nothing to fix before the new Ray's code. Fixing gdevpsdi.c ln 205 just forces a downsampling with the factor 1 due to the current downsampler handles integer factors only. Thus this change appears equivalent. Must wait for the Ray's patch. Igor.
Moving the bug to me until the image downsampling filter is available, then it will move back to igor for pdfwrite implementation.
*** This bug has been marked as a duplicate of 493348 ***
Changing customer bugs that have been resolved more than a year ago to closed.
(In reply to comment #13) > *** This bug has been marked as a duplicate of 493348 *** This is not really a duplicate. 493348 is about a particular kind of downsampling (interpolation). This bug is about downsampling only by integer scales. Ghostscript (still) can only scale by 2.0, 3.0, etc., so anything requiring downsampling of less than 2x doesn't get downsampled at all. This is in particular conflict with the default thresholds of 1.5. Until non-integer scaling is supported, there needs to be some warning when non-integer thresholds are specified (since they will be rounded or ignored). But Ghostscript should really be able to downscale by non-integer factors.