Bug 691435

Summary: any PDFSETTINGS besides /default gives dictfull error
Product: Ghostscript Reporter: Mark DeVries <mdevries>
Component: PDF WriterAssignee: Ken Sharp <ken.sharp>
Status: RESOLVED FIXED    
Severity: major CC: alex
Priority: P4    
Version: 8.63   
Hardware: PC   
OS: Windows XP   
Customer: Word Size: ---
Attachments: PostScript input file
error message with PDFSETTINGS=/screen
command used to distill PLAY file
Zip archive of a single (one image) EPS extracted from the original file

Description Mark DeVries 2010-06-30 14:01:02 UTC
Created attachment 6413 [details]
PostScript input file

Our customer produces graphics-rich manuals. This sample will distill with PDFSETTINGS=/default but produces a very large PDF file. They want to use /screen to reduce PDF filesize but all PDFSETTINGS except /default give
    Error: /dictfull in --image--

(My cut-down sample PS, 33 pages and 15MB, gives PDF size 10MB.  Our customer's PS is 500 pages and 140MB and gives PDF size 88MB.)

I reported this as gs 8.63, the one we use, but I tested it with gs 8.71 with identical results.

-Mark DeVries
SDL
Comment 1 Mark DeVries 2010-06-30 14:02:20 UTC
Created attachment 6414 [details]
error message with PDFSETTINGS=/screen
Comment 2 Mark DeVries 2010-06-30 14:02:58 UTC
Created attachment 6415 [details]
command used to distill PLAY file
Comment 3 Ken Sharp 2010-07-01 09:17:22 UTC
Created attachment 6422 [details]
Zip archive of a single (one image) EPS extracted from the original file

Reduced the original large PostScript file to a single EPS, extracted verbatim from the original file, which exhibits the issue.
Comment 4 Alex Cherepanov 2010-07-01 15:03:25 UTC
The error is triggered by  "/DownsampleGrayImages true" parameter.

The /dictfull error is caused by confusion between stream exit status and
interpreter return codes.

Index: gs/base/gdevpdfj.c
===================================================================
--- gs/base/gdevpdfj.c  (revision 11466)
+++ gs/base/gdevpdfj.c  (working copy)
@@ -650,10 +650,10 @@

        status = s_close_filters(&piw->binary[0].strm, piw->binary[0].target);
        if (status < 0)
-           return status;
+           return_error(gs_error_ioerror);
        status = s_close_filters(&piw->binary[1].strm, piw->binary[1].target);
        if (status < 0)
-           return status;
+           return_error(gs_error_ioerror);
     }
     pdf_choose_compression_cos(piw, s, end_binary);
     return 0;
Comment 5 Ken Sharp 2010-07-01 15:13:32 UTC
(In reply to comment #4)
> The error is triggered by  "/DownsampleGrayImages true" parameter.
> 
> The /dictfull error is caused by confusion between stream exit status and
> interpreter return codes.

Sorry Alex, I should have said I'd figured that out. The problem is due to the average downsample filter when closed. The image being written has less data than declared (declared image height 124, actual height before data exhausted 84) and the downsample filter does not seem able to cope with this and returns an error.

I've been looking at whether we can fail more gracefully.
Comment 6 Ken Sharp 2010-07-01 15:15:16 UTC
FWIW this is another example of silly PostScript being created by tiff2ps. For some reason it does not emit the whole image in one go, but instead runs a loop which draws draws an image of 124 lines height. It does this until the data is exhausted which means the last image is short. 

PostScript tolerates that of course.
Comment 7 Ken Sharp 2010-07-01 15:58:08 UTC
OK the actual problem is the DCT filter, the screen filter additionally sets up DCT output for images.

You can't truncate the output half way through writing a DCT image, as chunks of the filter are set up using the height of the image as parameters (eg the zig-zag ordering). So if we get premature end of data while writing a JPEG image, we have to abort the JPEG processing.

It looks like in this case we *can* fall back gracefully to a simple Flate compressed representation of the image so I'll do that. I'll also fix the error reporting so that we get an ioerror instead of a misleading dictfull.
Comment 8 Ken Sharp 2010-07-01 19:11:27 UTC
Fixed in revision 11476. This is really more of a feature than a bug. If the image does not contain sufficient data for the declared size we cannot create a DCT encoded image from it. The error was misleading and that has been fixed.

As an enhancement, under these circumstances we will now fall back to a Flate encoded image instead if possible.

Patch here:
http://ghostscript.com/pipermail/gs-cvs/2010-July/011339.html
Comment 9 Alex Cherepanov 2010-07-01 21:21:58 UTC
I think, 
  return_error(gs_error_ioerror);
should be used instead of
  return gs_error_ioerror;

because the former traces the origin of the error
when -Z# flag is in effect.
Comment 10 Mark DeVries 2010-07-09 14:53:28 UTC
Fix works fine for us.  Thanks.