Ghostscript now implements imagemask interpolation, internally done with the /Imscale filter, which outputs a bitmap with 4 times the horizontal and vertical resolution of its input. However, the results don't exactly match Adobe. The current implementation is based on a 4x4 window of source pixels, addressing a lookup table. This gives results that are fairly close to Adobe's implementation, but not quite. On further analysis of test images, it looks like even a 5x5 window is not adequate to exactly predict the Adobe interpolation results. A Python script generating all 4x4 combinations is attached to this bug, as well as the results from an Adobe interpreter. The current results are probably "good enough," but if anyone can figure out the actual logic used, that would be much appreciated. Keep in mind that the algorithm was initially implemented on an 8 MHz 68000 family processor, to make 75 dpi MacPaint bitmap images print more smoothly on the then brand-new Apple LaserWriter. This suggests that the actual algorithm must be fairly simple and not too expensive in CPU or memory.
Created attachment 2597 [details] test case for analyzing Adobe imagemask interpolation imm2.py generates the test file used to render the resulting images. The four pbm files are the pages generated, in order. Rendering is 600dpi, so each pixel from the interpolation filter is actually rendered as a 2x2 block.
Raph, What format is the file that you attached to this bug report?
Sorry, it's a .tar.bz2 file. I should have realized that the bug tracker strips out the name of the file.
I am a freelance developer working on the this bug. I am working towards the bounty. My plan is to work in my off time in the next 1-2 weeks to finish this. My code converts the output of Ghostscript to 90% correlation to the Adobe pbms. My code does uses the same tables as Raphs code, no more. My code runs in 120 ms per page (not counting i/o) and would probably do fine on a 8 MHz mc68k. I will be modifying the zoom_line function in simscale.c to concur with my code. I will ensure that the code is not dependent on resolution. The Adobe pattern does not change on a lower level than 300 dpi, so my code will also not change the pattern at any lower level.
retest and reassign.
A VERY low priority issue since this is 'implementation dependent'
Enhancement still missing in Ghostscript 9.03
So to recap; Adobe used to have a special scaling routine that would upscale imagemasks in the style of the MAME scalers. (https://www.scale2x.it/) Raph came up with an approximation to Adobe's routine using a 4x4 window, and this works, and is in ghostscript to this day (for imagemasks that don't get scaled up by more than a factor of 2). This bug exists because Raph would have liked to get an exact match rather than an approximate match. Testing with Acrobat 9 Pro, I cannot get Acrobat to scale in this style at all any more. I suspect this is no more than a piece of historical interest at this point. There has been no progress on this bug in 12 years, and it seems likely that any will be forthcoming soon. So, I'm closing the bug.
Actually, there's progress. A 5x5 window is sufficient, and the resulting logical function can be made reasonably compact. I just need to grok Ghostscript streams to post a solution. Please reopen.
Created attachment 18874 [details] Patch This patch assumes that the pixels around the image are white. This is the same as it is done now. Adobe seems to have black pixels on the right (at the end of the scan line) and white pixels elsewhere. This bug has not been reproduced.
Created attachment 19428 [details] Large interpolation test file
Fixed with Peter's patch in: commit da755f7ee3da900a504a3265c64fb08c93a41eac Author: Robin Watts <Robin.Watts@artifex.com> Date: Wed Jul 8 16:41:11 2020 +0100 Bug 688990: Reimplementation of image mask scaling. Aiming for a better match to Adobe's reference implementation. Patch supplied by Peter Cherepanov. Many Thanks!