/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id: PageExtractor.java 1345683 2012-06-03 14:50:33Z gadams $ */

package org.apache.xmlgraphics.ps.dsc.tools;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.xmlgraphics.ps.DSCConstants;
import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.xmlgraphics.ps.dsc.DSCException;
import org.apache.xmlgraphics.ps.dsc.DSCFilter;
import org.apache.xmlgraphics.ps.dsc.DSCParser;
import org.apache.xmlgraphics.ps.dsc.DSCParserConstants;
import org.apache.xmlgraphics.ps.dsc.DefaultNestedDocumentHandler;
import org.apache.xmlgraphics.ps.dsc.events.DSCComment;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPage;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPages;
import org.apache.xmlgraphics.ps.dsc.events.DSCEvent;
import org.apache.xmlgraphics.ps.dsc.events.DSCHeaderComment;

This class can extract a certain range of pages from a DSC-compliant PostScript file.
/** * This class can extract a certain range of pages from a DSC-compliant PostScript file. */
public final class PageExtractor implements DSCParserConstants { private PageExtractor() { }
Parses a DSC-compliant file and pipes the content through to the OutputStream omitting all pages not within the range.
Params:
  • in – the InputStream to parse from
  • out – the OutputStream to write the modified file to
  • from – the starting page (1-based)
  • to – the last page (inclusive, 1-based)
Throws:
/** * Parses a DSC-compliant file and pipes the content through to the OutputStream omitting * all pages not within the range. * @param in the InputStream to parse from * @param out the OutputStream to write the modified file to * @param from the starting page (1-based) * @param to the last page (inclusive, 1-based) * @throws IOException In case of an I/O error * @throws DSCException In case of a violation of the DSC spec */
public static void extractPages(InputStream in, OutputStream out, int from, int to) throws IOException, DSCException { if (from <= 0) { throw new IllegalArgumentException("'from' page number must be 1 or higher"); } if (to < from) { throw new IllegalArgumentException( "'to' page number must be equal or larger than the 'from' page number"); } DSCParser parser = new DSCParser(in); PSGenerator gen = new PSGenerator(out); parser.addListener(new DefaultNestedDocumentHandler(gen)); int pageCount = 0; //Skip DSC header DSCHeaderComment header = DSCTools.checkAndSkipDSC30Header(parser); header.generate(gen); //Set number of pages DSCCommentPages pages = new DSCCommentPages(to - from + 1); pages.generate(gen); parser.setFilter(new DSCFilter() { public boolean accept(DSCEvent event) { if (event.isDSCComment()) { //Filter %%Pages which we add manually above return !event.asDSCComment().getName().equals(DSCConstants.PAGES); } else { return true; } } }); //Skip the prolog and to the first page DSCComment pageOrTrailer = parser.nextDSCComment(DSCConstants.PAGE, gen); if (pageOrTrailer == null) { throw new DSCException("Page expected, but none found"); } parser.setFilter(null); //Remove filter //Process individual pages (and skip as necessary) while (true) { DSCCommentPage page = (DSCCommentPage)pageOrTrailer; boolean validPage = (page.getPagePosition() >= from && page.getPagePosition() <= to); if (validPage) { page.setPagePosition(page.getPagePosition() - from + 1); page.generate(gen); pageCount++; } pageOrTrailer = DSCTools.nextPageOrTrailer(parser, (validPage ? gen : null)); if (pageOrTrailer == null) { throw new DSCException("File is not DSC-compliant: Unexpected end of file"); } else if (!DSCConstants.PAGE.equals(pageOrTrailer.getName())) { pageOrTrailer.generate(gen); break; } } //Write the rest while (parser.hasNext()) { DSCEvent event = parser.nextEvent(); event.generate(gen); } } }