diff options
author | Ralph Giles <ralph.giles@artifex.com> | 2009-07-28 16:49:26 +0000 |
---|---|---|
committer | Ralph Giles <ralph.giles@artifex.com> | 2009-07-28 16:49:26 +0000 |
commit | 9d2e5a36742cc16c112bed94057dd5cc60414eae (patch) | |
tree | c02f09f34477f2f90900413f5c3f26dca25cab18 /gs | |
parent | 346797ab8b52ee71f2f5417747d7a0f8dbb10e96 (diff) | |
download | ghostpdl-9d2e5a36742cc16c112bed94057dd5cc60414eae.tar.gz |
Work around problems with XInitImage and large rasters.
Patch from Russ Cox, fixes Bugs 689547 and 689561.
Details:
The patch sets bitmap_pad, and passes 0 for bytes_per_line in
cases were current xorg can correctly generate a value. Russ writes:
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.
git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@9898 a1074d23-0009-0410-80fe-cf8c14f379e6
Diffstat (limited to 'gs')
-rw-r--r-- | gs/base/gdevx.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/gs/base/gdevx.c b/gs/base/gdevx.c index af17b7390..ebd413129 100644 --- a/gs/base/gdevx.c +++ b/gs/base/gdevx.c @@ -565,15 +565,24 @@ x_copy_image(gx_device_X * xdev, const byte * base, int sourcex, int raster, 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; |