Created attachment 7359 [details] 58283.pdf The customer reports I've verified that gs9.01 hangs when the attached file is ripped at 300dpi. I've duplicated this with 9.01 and head (r12281). The command line I'm using for testing: bin/gs -sDEVICE=tiff24nc -o test.tif -r300 ./58283.pdf
Further information from the customer: When ripping the attached file with GS 9.01 the program works fine at e.g. 100 and 200 dpi but at 300 dpi or higher it hangs. The effect can also be seen with Ghostview (version 4.9 with GS 9.01) when zooming in enough; I could see *no* progress. Strange is that in GS as well as Adobe Reader 9.4.2 there are quite large rastered areas (grey/white and green/white) whereas in Foxit 4.3.1 these aras are white. Also, there are *no* callbacks (as specified in the init function of the DLL) at the time GS hangs. Most of the time seems to be used in the loop in gxacpath.c, function accum_fill_rectangle, lines 476..477: === /* Work backwards till we find the insertion point. */ while (ye <= rptr->ymin) rptr = rptr->prev; === Parameters for gswin32c: -P- -dBATCH -dNOPAUSE -Z: -r300x300 -sOUTPUTFILE=38028.tif -sDEVICE=tiff24nc -dFirstPage=1 -dLastPage=1 -dNOCIE -dNOPSICC -dUseCropBox -d.IgnoreNumCopies=true -c (58283.pdf) run Famous last words: ===> % Init started, instance 0x003F5F88, with args: -dDisplayFormat=198788 -dDisplayResolution=96 -P- -dBATCH -dNOPAUSE -Z: -r300x300 -sOUTPUTFILE=38028.tif -sDEVICE=tiff24nc -dFirstPage=1 -dLastPage=1 -dNOCIE -dNOPSICC -dUseCropBox -d.IgnoreNumCopies=true -c (d:/58283.pdf) run GPL Ghostscript 9.01 (2011-02-07) Copyright (C) 2010 Artifex Software, Inc. All rights reserved. This software comes with NO WARRANTY: see the file PUBLIC for details. [:]width=2479, band_width=2479, band_height=456, nbands=8 [:]width=2479, band_width=2479, band_height=456, nbands=8 % Start time = 1.843, memory allocated = 1580512, used = 1425077 pdfpagecount=1 Processing pages 1 through 1. Page 1 [:]width=16538, band_width=16538, band_height=68, nbands=158 [:]width=16538, band_width=16538, band_height=68, nbands=158 Can't find (or can't open) font file %rom%Resource/Font/ArialMT. Can't find (or can't open) font file ArialMT. Can't find (or can't open) font file %rom%Resource/Font/ArialMT. Can't find (or can't open) font file ArialMT. Querying operating system for font files... Didn't find this font on the system! Substituting font Helvetica for ArialMT. Loading NimbusSanL-Regu font from %rom%Resource/Font/NimbusSanL-Regu... 2524896 1191873 1947640 650172 3 done. Substituting font Helvetica-Narrow for ArialNarrow. Loading NimbusSanL-ReguCond font from %rom%Resource/Font/NimbusSanL-ReguCond... 2601872 1294323 2152620 848878 3 done. [:]clist_end_page at cfile=10581, bfile=120 <===
This is a regression, the problem started with: ------------------------------------------------------------------------ r11579 | ray | 2010-07-30 17:37:07 -0700 (Fri, 30 Jul 2010) | 6 lines Fix the calculation of the size of the pattern bitmap by correcting the calculation of the effective depth (bits per pixel). PaintType 2 is the uncolored (mask == 1 bit per pixel) mode, PaintType 1 is colored, thus needs the full target device color_info.depth bits per pixel. Bug 691514 detected running the PDF 1.7 FTS for customer 532. ------------------------------------------------------------------------
P1 for regression and hang.
I am looking into this and have found an area of code that may be the root cause. As a temporary work around, the following halps. The PDF contains: %Resolving: [102 0] %Pattern: << /PaintType 1 /XStep 128 /PaintProc {<< /XObject << /Im2 {32 0 resolveR} >> /ExtGState << /GS1 {90 0 resolve R} >> /ColorSpace << /Cs10 {101 0 resolveR} /Cs6 {82 0 resolveR} >> /ProcSet [/PDF /ImageC /ImageI] >> .pdfpaintproc} /Resources {102 0 resolveR} /YStep 32 /.pattern_uses_transparency false /PatternType 1 /Matrix [-2.13028193 0 0 -33.4684372 741.559387 1243.65186] /Filter /FlateDecode /TilingType 1 /Type /Pattern /BBox [0 0 128 32] /Length 51 /File (...) >> At 300 dpi, the pattern is 4463 by 1137 pixels so with a depth of 24 bits this calculates (correctly) a bitmap size of 15,223,293 bytes which exceeds the default MaxPatternBitmap of 8Mb. Setting -dMaxPatternBitmap=32000000 this completes on my laptop in 58 seconds. It takes 48 seconds to write the clist which is 114,407,724 Mb. Note that adding -dBufferSpace=32000000 (so that only 20 bands are needed instead of 158) completes in 51 seconds. -----------------------
The time is being spent turning a large mask (1143x4471 landscape) into a clip list (ordered list of rectangles) which is started by gx_image_fill_masked_start detects that the pattern is a clist. This is so that we don't play back the clist for each and every 'fill_masked' that happens when the pattern is a tile. For this landscape image 8 bit wide "swaths" of the image (full height) are collected and then fed into the clip accumulator as 'copy_mono' calls. The clip accumulator expects that it will be fed with y-ordered calls, so it searches the list of rectangles from the tail back. This is fine for the first swath that is painted with increasing y order, but for subsequent swaths, it must search all the way back to the start of the list to insert new rectangles. As more and more of the mask is turned into rectangles in the clip list, this gets worse and worse, particularly since each group of rectangles across x grows. We need a smarter way of turning an image mask into the correct sequence of rectangles. Ideas come to mind like collecting the list x-major (for this case) then converting to y-major just once. or using a binary tree for the y list and the list of rectangles in x order at each y entry. Others may have code laying around we can apply, so I'll email tech and ask for ideas.
This can be handled fairly simply. Instead of holding a single sorted list into which we insert each new rectangle, instead, we hold 2 sorted lists. Let's call them master and temp. Whenever we get a new edge in, we check to see if it can be trivially inserted into the top or bottom of temp. If it can't, then we merge temp with master, and restart a new temp list that contains just the single rectangle. This means that in the example given, most of our insertions are simple head/tail additions. The ones that aren't result in merges of 2 lists (an O(n) process). This also copes nicely with the cases where the images are rotated by 180 degrees from the normal portrait/landscape cases, and the y ordering on incoming rectangles tends to be reversed.
Fixed in: commit da1152191fb97516b82303ab187b08c971bfd360 Author: Robin Watts <Robin.Watts@artifex.com> Date: Mon Jun 20 17:57:46 2011 +0100 Fix Bug 692057, 'hang' while converting mask->rectangle list. Previously the clip accumulator code would attempt to add a new rectangle would always search backwards from the tail of the list when looking for a new place to insert a rectangle. This works well when rectangles are coming in at (or near) the end of the list. For cases where this doesn't happen we quickly break down to O(n^2) operation. The example file on the bug shows one such circumstance, where we process a landscape image; this results in the masks coming in as '8 bit columns'. The first column accumulates nicely, subsequent ones do not. The fix here, as suggested by Chris Liddell, is to store the 'last insert point', and to search from that. Locality of reference should pay off here and lead to much improved performance. Certainly tests with the example file show that we complete within 2.5 minutes on my machine, compared to 1.5 minutes with -dMaxPatternBitmap=32000000, and an unknown time over 5 minutes with the old code. (Old code was tested on Rays machine and took over 2 hours before we gave up and killed it).