On large bitmaps, calls to XInitImage fail, producing an /unknownerror in builtin ops like fill or show. For example, if you run gv on http://pdos.csail.mit.edu/~rsc/pprof.ps, it dies with the gs error: Error: /unknownerror in --fill-- Operand stack: --nostringval-- Execution stack: %interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push 1905 1 3 %oparray_pop 1904 1 3 %oparray_pop 1888 1 3 %oparray_pop 1771 1 3 %oparray_pop --nostringval-- %errorexec_pop .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- Dictionary stack: --dict:1124/1684(ro)(G)-- --dict:0/20(G)-- --dict:71/200(L)-- --dict:36/200(L)-- Current allocation mode is local GPL Ghostscript SVN PRE-RELEASE 8.61: Unrecoverable error, exit code 1 Alternately, you can load almost any PostScript file and zoom in to scale 4x or 8x or 10x. All that matters is that the image bitmap for the entire page is very wide. I have tracked down the problem, and it appears to be a bad interaction between gs and recent sanity checking in the X library. In particular, sometimes x_copy_image in gdevx.c gets called with wide widths but narrow raster values. Even though the raster is apparently wrong, the X graphics operations would work okay with that value. But new versions of X11 have various checks in XInitImage, one of which is that the raster is greater than or equal to the width of the image times the depth. To see that this diagnosis is correct, replacing the call to XInitImage with a call to _XInitImageFuncPtrs (which is just XInitImage without the sanity checking) makes gs start working. But of course _XInitImageFuncPtrs is not a public interface function and thus probably not the best fix. Replacing the "bytes_per_line = raster" with "bytes_per_line = 0" (which makes X compute the value from width and depth) works fine in the zoom levels that would otherwise crash but causes the previously-working zoom levels to shear the image (or worse), presumably because the "obvious" raster is not the right one at those levels. Also, the new XInitImage also requires bitmap_pad be set always. The patch below also fixes the problem -- I can run "gv pprof.ps" at all zoom levels, and I can also zoom into regular documents. Perhaps it is not the right fix -- perhaps the actual bug is that x_copy_image is being called with a bad raster value in the first place. But it does work. $ svn diff gdevx.c Index: gdevx.c =================================================================== --- gdevx.c (revision 8346) +++ gdevx.c (working copy) @@ -565,15 +565,24 @@ X_SET_FORE_COLOR(xdev, pixel); XDrawPoint(xdev->dpy, xdev->dest, xdev->gc, x, y); } else { - xdev->image.width = sourcex + w; + /* Reduce base, sourcex */ + int width = sourcex + w; + int vdepth = xdev->vinfo->depth; + xdev->image.width = width; xdev->image.height = h; xdev->image.format = ZPixmap; xdev->image.data = (char *)base; - xdev->image.depth = xdev->vinfo->depth; - xdev->image.bytes_per_line = raster; + xdev->image.depth = vdepth; + xdev->image.bitmap_pad = 8; + if (width * vdepth < raster * 8) + xdev->image.bytes_per_line = raster; + else + xdev->image.bytes_per_line = 0; xdev->image.bits_per_pixel = depth; - if (XInitImage(&xdev->image) == 0) + if (XInitImage(&xdev->image) == 0){ + errprintf("XInitImage failed in x_copy_image.\n"); return_error(gs_error_unknownerror); + } XPutImage(xdev->dpy, xdev->dest, xdev->gc, &xdev->image, sourcex, 0, x, y, w, h); xdev->image.depth = xdev->image.bits_per_pixel = 1; $
Is this the same as bug #689561?
Created attachment 4963 [details] pprof.ps - local copy of the sample file
*** Bug 689561 has been marked as a duplicate of this bug. ***
I don't know if the raster value is wrong either, but the patch certainly does resolve the issue. Committed as r9898, it will be in the 8.70 release. Thanks!