0

i made a Java application whose purpose is to offer a Print Preview for PS files.

My program uses Ghostscript and Ghost4J to load the Post Script file and produces a list of Images (one for each page) using the SimpleRenderer.render method. Then using a simple JList i show only the image corresponding to the page the user selected in JList.

This worked fine until a really big PS file occurred, causing an OutOfMemoryError when executing the code

PSDocument pdocument = new PSDocument(new File(filename));

I know that is possibile to read a file a little at a time using InputStreams, the problem is that i can't think of a way to connect the bytes that i read with the actual pages of the document.

Example, i tried to read from PS file 100 MB at a time

int buffer_size = 100000000;
byte[] buffer = new byte[buffer_size];

FileInputStream partial = new FileInputStream(filename);
partial.read(buffer, 0, buffer_size);
document.load(new ByteArrayInputStream(buffer));

SimpleRenderer renderer = new SimpleRenderer();

//how many pages do i have to read?
List<Image> images = renderer.render(document, firstpage ??, lastpage ??);

Am i missing some Ghost4J functionality to read partially a file? Or has someone other suggestions / approaches about how to solve this problem in different ways? I am really struggling

KenS
  • 30,202
  • 3
  • 34
  • 51
Mirai
  • 31
  • 1
  • 4
  • 1
    I don't know this file format but I think it's quite likely to be impossible to parse a partially-read file. – g00se Jan 04 '23 at 10:43
  • I agree, with the solution i posted my application is a bit slow when i have to load a new set of pages, but considering is a print program, maybe the user has no real interest in navigating all the pages of file in the Print Preview – Mirai Jan 05 '23 at 14:25

1 Answers1

0

I found out I can use Ghost4J Core API to retrieve from a Post Script file a reduced set of pages as Images.

Ghostscript gs = Ghostscript.getInstance();

String[] gsArgs = new String[9];
        gsArgs[0] = "-dQUIET";
        gsArgs[1] = "-dNOPAUSE";
        gsArgs[2] = "-dBATCH";
        gsArgs[3] = "-dSAFER";
        gsArgs[4] = "-sDEVICE=display";
        gsArgs[5] = "-sDisplayHandle=0";
        gsArgs[6] = "-dDisplayFormat=16#804";
        gsArgs[7] = "-sPageList="+firstPage+"-"+lastPage;
        gsArgs[8] = "-f"+filename;
        
         //create display callback (capture display output pages as images)
  ImageWriterDisplayCallback displayCallback = new ImageWriterDisplayCallback();
 
        //set display callback
        gs.setDisplayCallback(displayCallback);
        
        //run PostScript (also works with PDF) and exit interpreter
        try {
 
            gs.initialize(gsArgs);
            gs.exit();
            Ghostscript.deleteInstance();
 
        } catch (GhostscriptException e) {
            System.out.println("ERROR: " + e.getMessage());
            e.printStackTrace();
        }

       return displayCallback.getImages(); //return List<Images>

This solve the problem of rendering page as images in the preview.

However, i could not find a way to use Ghost4J to know total number of pages of PS file (in case the file is too big for opening it with Document.load()).

So, i am still here needing some help

Mirai
  • 31
  • 1
  • 4
  • 1
    I just used this Ghostscript command successfully to print the number of pages in input.pdf so you might be able to adapt it: `gs -q -dNODISPLAY --permit-file-read=input.pdf -c "(input.pdf) (r) file runpdfbegin pdfpagecount = quit" ` I know next to nothing about Ghostscript but @K-J might be able to help – g00se Jan 05 '23 at 13:45
  • Thank you! I will try to adapt it with a PS file, where did you fine this command? I have read a lot on Ghostscript documentation, didn't find anything. I am not so good in english maybe i missed it – Mirai Jan 05 '23 at 14:29
  • 1
    I found a lot of similar commands from googling but had to do quite a bit of trial and error before I could get it to work on my system. `pdfinfo` is easier ;) – g00se Jan 05 '23 at 14:49
  • Fiendish stuff ;) – g00se Jan 10 '23 at 12:07