--- /dev/null
+/*
+ * Copyright (c) 2009, Takeyuki Nagao
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+package jp.sourceforge.dvibrowser.dvicore.cli.tools;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.imageio.ImageIO;
+
+import jp.sourceforge.dvibrowser.dvicore.DviException;
+import jp.sourceforge.dvibrowser.dvicore.DviObject;
+import jp.sourceforge.dvibrowser.dvicore.DviPaperSize;
+import jp.sourceforge.dvibrowser.dvicore.DviRect;
+import jp.sourceforge.dvibrowser.dvicore.DviResolution;
+import jp.sourceforge.dvibrowser.dvicore.api.DviContext;
+import jp.sourceforge.dvibrowser.dvicore.api.DviContextSupport;
+import jp.sourceforge.dvibrowser.dvicore.api.DviDocument;
+import jp.sourceforge.dvibrowser.dvicore.api.DviPage;
+import jp.sourceforge.dvibrowser.dvicore.ctx.DefaultDviContext;
+import jp.sourceforge.dvibrowser.dvicore.gui.swing.ViewSpec;
+import jp.sourceforge.dvibrowser.dvicore.image.split.ImageFileConfig;
+import jp.sourceforge.dvibrowser.dvicore.util.Benchmark;
+import jp.sourceforge.dvibrowser.dvicore.util.DviUtils;
+import jp.sourceforge.dvibrowser.dvicore.util.ZipBuilder;
+
+
+public class ConvertToImage
+extends DviObject
+{
+ private static final String OPT_SHRINK_FACTOR = "--shrink-factor=";
+ private static final String OPT_DPI = "--dpi=";
+ private static final String OPT_OUTPUT_FILE = "--output-file=";
+ private static final String OPT_RESOURCES_FILE = "--resources-file=";
+ private static final String OPT_PAPER_SIZE = "--paper-size=";
+ private static final String OPT_USE_BBOX = "--use-bbox=";
+ private static final String OPT_PADDING = "--padding=";
+ private static final Logger LOGGER = Logger.getLogger(ConvertToImage.class
+ .getName());
+
+ public static class Config
+ extends DviObject
+ {
+ private final ViewSpec viewSpec;
+ private final ArrayList<File> inputs = new ArrayList<File>();
+ private boolean useBoundingBox;
+ private File outputFile;
+ private DviPaperSize paperSize;
+ private ImageFileConfig imageFileConfig;
+ private int padding;
+ private File resourcesFile;
+
+ public Config(DviContextSupport dcs) {
+ super(dcs);
+ viewSpec = new ViewSpec(dcs);
+ try {
+ setPaperSize(getDviContext().getDefaultPaperSize());
+ } catch (DviException e) {
+ DviUtils.logStackTrace(LOGGER, Level.WARNING, e);
+ setPaperSize(DviPaperSize.FALLBACK);
+ }
+ // TODO: outsource the config.
+ imageFileConfig = ImageFileConfig.PNG;
+ padding = 0;
+ }
+
+ public void setDpi(int dpi)
+ {
+ viewSpec.setResolution(new DviResolution(dpi, viewSpec.getResolution().shrinkFactor()));
+ }
+
+ public void setShrinkFactor(int sf)
+ {
+ viewSpec.setResolution(new DviResolution(viewSpec.getResolution().dpi(), sf));
+ }
+
+ public ViewSpec getViewSpec() {
+ return viewSpec;
+ }
+
+ public void setUseBoundingBox(boolean crop) {
+ this.useBoundingBox = crop;
+ }
+
+ public boolean useBoundingBox() { return useBoundingBox; }
+
+ public void setOutputFile(File outputFile) {
+ if (outputFile != null) {
+ this.outputFile = outputFile;
+ } else {
+ this.outputFile = null;
+ }
+ }
+
+ public void addInputFile(File file)
+ {
+ if (file != null) {
+ inputs.add(file);
+ } else {
+ LOGGER.warning("Input file is null. Ignored.");
+ }
+ }
+
+ public File getOutputFile() {
+ return outputFile;
+ }
+
+ public DviPaperSize getPaperSize() {
+ return paperSize;
+ }
+
+
+ public ArrayList<File> getInputs() {
+ return inputs;
+ }
+
+ public void parseArguments(String [] args) throws DviException
+ {
+ final DviContext ctx = getDviContext();
+ for (int i=0; i<args.length; i++) {
+ String a = args[i];
+ if (a.startsWith(OPT_DPI)) {
+ int dpi = Integer.parseInt(a.substring(OPT_DPI.length()));
+ setShrinkFactor(dpi);
+ } else if (a.startsWith(OPT_SHRINK_FACTOR)) {
+ int sf = Integer.parseInt(a.substring(OPT_SHRINK_FACTOR.length()));
+ setShrinkFactor(sf);
+ } else if (a.startsWith(OPT_PADDING)) {
+ int padding = Integer.parseInt(a.substring(OPT_PADDING.length()));
+ setPaddingSize(padding);
+ } else if (a.startsWith(OPT_PAPER_SIZE)) {
+ String s = a.substring(OPT_PAPER_SIZE.length());
+ DviPaperSize paperSize = ctx.findPaperSizeByName(s);
+ if (paperSize == null) {
+ throw new DviException("Unrecognized papersize: " + s);
+ }
+ } else if (a.startsWith(OPT_RESOURCES_FILE)) {
+ String s = a.substring(OPT_RESOURCES_FILE.length()).trim();
+ if (!"".equals(s)) {
+ setResourcesFile(new File(s));
+ } else {
+ throw new DviException("Output filename is empty.");
+ }
+ } else if (a.startsWith(OPT_OUTPUT_FILE)) {
+ String s = a.substring(OPT_OUTPUT_FILE.length()).trim();
+ if (!"".equals(s)) {
+ setOutputFile(new File(s));
+ } else {
+ throw new DviException("Output filename is empty.");
+ }
+ } else if (a.startsWith(OPT_USE_BBOX)) {
+ String s = a.substring(OPT_USE_BBOX.length()).trim();
+ if ("yes".equalsIgnoreCase(s)) {
+ setUseBoundingBox(true);
+ } else if ("no".equalsIgnoreCase(s)) {
+ setUseBoundingBox(false);
+ } else {
+ throw new DviException("Invalid parameter value: " + a);
+ }
+ } else if (a.startsWith("-")) {
+ throw new DviException("Unrecognized commandline option: " + a);
+ } else {
+ for (; i<args.length; i++) {
+ a = args[i];
+ addInputFile(new File(a));
+ }
+ }
+ }
+ }
+
+ private void setResourcesFile(File file) {
+ this.resourcesFile = file;
+ }
+
+ public File getResourcesFile() {
+ return resourcesFile;
+ }
+
+ private void setPaddingSize(int padding) {
+ this.setPadding(padding);
+ }
+
+ public void setPaperSize(DviPaperSize paperSize) {
+ this.paperSize = paperSize;
+ }
+
+ public ImageFileConfig getImageFileConfig()
+ {
+ return imageFileConfig;
+ }
+
+ public void setImageFileConfig(ImageFileConfig imageFileConfig) {
+ this.imageFileConfig = imageFileConfig;
+ }
+
+ public static String getUsage()
+ {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ pw.println("usage: java " + ConvertToImage.class.getName() + " [options] <input-files>");
+ pw.println(" options: ");
+ pw.println(" --dpi=N Set output DPI to N");
+ pw.println(" --shrink-factor=N Set shrink factor to N (1--1024)");
+ pw.println(" --output-file=F Set output zip file to F");
+ pw.println(" --resources-file=F Set resources file to F");
+ pw.println(" --padding=N Set padding size to N");
+ return sw.toString();
+ }
+
+ public void showUsage()
+ {
+ System.err.println(getUsage());
+ }
+
+ public boolean isValid() {
+ return getInputs().size() > 0;
+ }
+
+ public void setPadding(int padding) {
+ this.padding = padding;
+ }
+
+ public int getPadding() {
+ return padding;
+ }
+ }
+
+ public ConvertToImage(DviContextSupport dcs) {
+ super(dcs);
+ }
+
+ public int convert(Config config) throws Exception {
+ DviContext ctx = getDviContext();
+ ViewSpec vs = config.getViewSpec();
+ DviResolution res = vs.getResolution();
+ File outputFile = config.getOutputFile();
+ OutputStream os = null;
+ if (outputFile != null) {
+ if (!outputFile.getName().toLowerCase().endsWith(".zip")) {
+ outputFile = new File(outputFile.getParentFile(), outputFile.getName() + ".zip");
+ }
+ os = new FileOutputStream(outputFile);
+ LOGGER.info("Writing outputs to " + outputFile);
+ } else {
+ os = new FilterOutputStream(System.out) {
+ @Override
+ public void close()
+ {
+ // We don't close the stdout.
+ }
+ };
+ }
+ ZipBuilder zb = new ZipBuilder(os);
+
+ try {
+ for (File file : config.getInputs()) {
+ try {
+ DviDocument doc = ctx.openDviDocument(file);
+ LOGGER.info("Processing file: " + file);
+ for (int i=0; i<doc.getTotalPages(); i++) {
+ DviPage page = doc.getPage(i);
+ LOGGER.info("Processing page " + (i + 1) + "/" + doc.getTotalPages());
+ DviRect bbox;
+ if (config.useBoundingBox()) {
+ bbox =
+ ctx.getDviToolkit().computeBoundingBox(page, res);
+ } else {
+ bbox = config.getPaperSize().toBoundingBox(res);
+ }
+ bbox = bbox.addPadding(config.getPadding());
+
+ BufferedImage img = ctx.getDviToolkit().renderToBufferedImage(page, bbox, vs);
+ if (img == null) {
+ throw new DviException("Failed to render page " + (i + 1));
+ }
+
+ OutputStream imageOut = zb.openOutputStream
+ (String.format("%04d%s", i+1, config.getImageFileConfig().getImageExtension()));
+ try {
+ ImageIO.write(img, config.getImageFileConfig().getImageType(), imageOut);
+ } finally {
+ DviUtils.silentClose(imageOut);
+ }
+ }
+ } catch (DviException e) {
+ DviUtils.logStackTrace(LOGGER, Level.SEVERE, e);
+ throw e;
+ }
+ }
+ } finally {
+ DviUtils.silentClose(zb);
+ }
+ return 0;
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ DefaultDviContext ctx = new DefaultDviContext();
+
+ Config config = new Config(ctx);
+ config.parseArguments(args);
+
+ if (!config.isValid()) {
+ config.showUsage();
+ throw new DviException
+ ("Unrecognized command line: " + DviUtils.join(" ", args));
+ }
+
+ File resourcesFile = config.getResourcesFile();
+
+ if (resourcesFile != null) {
+ ctx.setRecordResources(true);
+ }
+
+ Benchmark benchmark = new Benchmark();
+ benchmark.begin("dvi rendering");
+ benchmark.addSample();
+ ConvertToImage app = new ConvertToImage(ctx);
+ int retcode = app.convert(config);
+ benchmark.end();
+
+ if (resourcesFile != null) {
+ Set<URL> resources = ctx.getRecordedResources();
+ FileOutputStream fos = new FileOutputStream(resourcesFile);
+ PrintWriter out = new PrintWriter(fos);
+ for (URL url : resources) {
+ out.println(url);
+ }
+ out.flush();
+ out.close();
+ fos.close();
+ }
+
+ LOGGER.info("Finished: " + benchmark.format());
+ // INT_ARGB: Finished: Benchmark result: dvi rendering: 1 samples in 68.182 sec. 0.015 samples/sec. 68182 msec./sample.
+ // INT_RGB: Finished: Benchmark result: dvi rendering: 1 samples in 62.976 sec. 0.016 samples/sec. 62976 msec./sample.
+ System.exit(retcode);
+ } catch (Exception e) {
+ DviUtils.logStackTrace(LOGGER, Level.WARNING, e);
+ System.exit(1);
+ }
+ }
+
+}