fixes for ghostscript 9.54+

This commit is contained in:
Jörg Prante 2024-04-30 22:57:10 +02:00
parent 27fd1956a1
commit 229951349b
13 changed files with 143 additions and 347 deletions

View file

@ -1,3 +1,3 @@
group = org.xbib.graphics group = org.xbib.graphics
name = graphics name = graphics
version = 5.4.0 version = 5.5.0

View file

@ -2,23 +2,20 @@ package org.xbib.graphics.ghostscript;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.IntByReference;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.xbib.graphics.ghostscript.internal.ErrorCodes; import org.xbib.graphics.ghostscript.internal.ErrorCodes;
import org.xbib.graphics.ghostscript.internal.GhostscriptLibrary; import org.xbib.graphics.ghostscript.internal.GhostscriptLibrary;
import org.xbib.graphics.ghostscript.internal.GhostscriptLibraryLoader; import org.xbib.graphics.ghostscript.internal.GhostscriptLibraryLoader;
import org.xbib.graphics.ghostscript.internal.LoggingOutputStream;
import org.xbib.graphics.ghostscript.internal.NullOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -33,21 +30,12 @@ public class Ghostscript implements AutoCloseable {
private final GhostscriptLibrary libraryInstance; private final GhostscriptLibrary libraryInstance;
private InputStream stdIn;
private OutputStream stdOut;
private OutputStream stdErr;
private final AtomicBoolean closed; private final AtomicBoolean closed;
public Ghostscript() throws IOException { public Ghostscript() throws IOException {
prepareTmp(); prepareTmp();
GhostscriptLibraryLoader libraryLoader = new GhostscriptLibraryLoader(); GhostscriptLibraryLoader libraryLoader = new GhostscriptLibraryLoader();
this.libraryInstance = libraryLoader.getGhostscriptLibrary(); this.libraryInstance = Objects.requireNonNull(libraryLoader.getGhostscriptLibrary(), "library instance must not be null");
Objects.requireNonNull(this.libraryInstance);
this.stdOut = new LoggingOutputStream(logger);
this.stdErr = new LoggingOutputStream(logger);
this.closed = new AtomicBoolean(false); this.closed = new AtomicBoolean(false);
} }
@ -68,62 +56,7 @@ public class Ghostscript implements AutoCloseable {
return result; return result;
} }
/** public synchronized int run(List<String> args) throws IOException {
* Gets the error output stream of the Ghostscript interpreter (may be null
* if not set).
*
* @return The OutputStream or null
*/
public OutputStream getStdErr() {
return stdErr;
}
/**
* Sets the error output stream of the Ghostscript interpreter.
*
* @param outputStream OutputStream object
*/
public void setStdErr(OutputStream outputStream) {
stdErr = outputStream;
}
/**
* Gets the standard output stream of the Ghostscript interpreter.
*
* @return The OutputStream or null
*/
public OutputStream getStdOut() {
return stdOut;
}
/**
* Sets the standard output stream of the Ghostscript interpreter.
*
* @param outputStream OutputStream object
*/
public void setStdOut(OutputStream outputStream) {
stdOut = outputStream;
}
/**
* Gets the standard input stream of the Ghostscript interpreter.
*
* @return The InputStream or null
*/
public InputStream getStdIn() {
return stdIn;
}
/**
* Sets the standard input stream of the Ghostscript interpreter.
*
* @param inputStream InputStream object
*/
public void setStdIn(InputStream inputStream) {
stdIn = inputStream;
}
public synchronized int run(String[] args) throws IOException {
return run(args, null, null); return run(args, null, null);
} }
@ -136,9 +69,15 @@ public class Ghostscript implements AutoCloseable {
* @return the ghostscript return code; * @return the ghostscript return code;
* @throws IOException if initialize fails * @throws IOException if initialize fails
*/ */
public synchronized int run(String[] args, public synchronized int run(List<String> args,
String runString, String runString,
String fileName) throws IOException { String fileName) throws IOException {
Objects.requireNonNull(args);
List<String> fullArgList = new LinkedList<>();
if (!args.contains("ps2pdf")) {
fullArgList.add("gs"); // gs or ps2pdf must be always present in the arg list
}
fullArgList.addAll(args);
GhostscriptLibrary.gs_main_instance.ByReference nativeInstanceByRef = null; GhostscriptLibrary.gs_main_instance.ByReference nativeInstanceByRef = null;
int ret = 0; int ret = 0;
boolean quit = false; boolean quit = false;
@ -149,47 +88,16 @@ public class Ghostscript implements AutoCloseable {
nativeInstanceByRef = null; nativeInstanceByRef = null;
throw new IOException("can not call Ghostscript gsapi_new_instance, error code = " + ret); throw new IOException("can not call Ghostscript gsapi_new_instance, error code = " + ret);
} }
logger.log(Level.INFO, "ghostscript instance " + nativeInstanceByRef + " created"); logger.log(Level.FINE, "ghostscript instance " + nativeInstanceByRef + " created");
Pointer pointer = nativeInstanceByRef.getValue(); Pointer pointer = nativeInstanceByRef.getValue();
GhostscriptLibrary.stdin_fn stdinCallback = null; // always 0, we never use stdin
if (getStdIn() != null) { GhostscriptLibrary.stdin_fn stdinCallback = (caller_handle, buf, len) -> 0;
stdinCallback = (caller_handle, buf, len) -> { GhostscriptLibrary.stdout_fn stdoutCallback = (caller_handle, str, len) -> {
String encoding = System.getProperty(ENCODING_PARAMETER, "UTF-8"); logger.log(Level.FINE, str.substring(0, len));
try {
byte[] buffer = new byte[1024];
int read = getStdIn().read(buffer);
if (read != -1) {
buf.setString(0, new String(buffer, 0, read, encoding));
return read;
}
} catch (Exception e) {
logger.log(Level.WARNING, e.getMessage(), e);
}
return 0;
};
}
GhostscriptLibrary.stdout_fn stdoutCallback;
if (getStdOut() == null) {
setStdOut(new NullOutputStream());
}
stdoutCallback = (caller_handle, str, len) -> {
try {
getStdOut().write(str.getBytes(), 0, len);
} catch (IOException ex) {
logger.log(Level.WARNING, ex.getMessage(), ex);
}
return len; return len;
}; };
GhostscriptLibrary.stderr_fn stderrCallback; GhostscriptLibrary.stderr_fn stderrCallback = (caller_handle, str, len) -> {
if (getStdErr() == null) { logger.log(Level.FINE, str.substring(0, len));
setStdErr(new NullOutputStream());
}
stderrCallback = (caller_handle, str, len) -> {
try {
getStdErr().write(str.getBytes(), 0, len);
} catch (IOException ex) {
logger.log(Level.WARNING, ex.getMessage(), ex);
}
return len; return len;
}; };
logger.log(Level.FINE, "setting gsapi_set_stdio"); logger.log(Level.FINE, "setting gsapi_set_stdio");
@ -197,8 +105,8 @@ public class Ghostscript implements AutoCloseable {
if (ret != 0) { if (ret != 0) {
throw new IOException("can not set stdio on Ghostscript interpreter, error code " + ret); throw new IOException("can not set stdio on Ghostscript interpreter, error code " + ret);
} }
logger.log(Level.FINE, "gsapi_init_with_args = " + (args != null ? Arrays.asList(args) : "null")); logger.log(Level.FINE, "gsapi_init_with_args = " + fullArgList);
ret = libraryInstance.gsapi_init_with_args(pointer, args != null ? args.length : 0, args); ret = libraryInstance.gsapi_init_with_args(pointer, fullArgList.size(), fullArgList.toArray(new String[0]));
logger.log(Level.FINE, "gsapi_init_with_args return code = " + ret); logger.log(Level.FINE, "gsapi_init_with_args return code = " + ret);
if (ret == ErrorCodes.gs_error_Quit) { if (ret == ErrorCodes.gs_error_Quit) {
quit = true; quit = true;
@ -246,12 +154,12 @@ public class Ghostscript implements AutoCloseable {
Pointer pointer = nativeInstanceByRef.getValue(); Pointer pointer = nativeInstanceByRef.getValue();
if (pointer != null) { if (pointer != null) {
if (!quit && ret >= 0) { if (!quit && ret >= 0) {
logger.log(Level.INFO, "exiting ghostscript instance " + libraryInstance); logger.log(Level.FINE, "exiting ghostscript instance " + libraryInstance);
ret = libraryInstance.gsapi_exit(pointer); ret = libraryInstance.gsapi_exit(pointer);
if (ret != 0) { if (ret != 0) {
logger.log(Level.SEVERE, "can not call Ghostscript gsapi_exit, error code " + ret); logger.log(Level.SEVERE, "can not call Ghostscript gsapi_exit, error code " + ret);
} }
logger.log(Level.INFO, "deleting ghostscript instance " + pointer); logger.log(Level.FINE, "deleting ghostscript instance " + pointer);
libraryInstance.gsapi_delete_instance(pointer); libraryInstance.gsapi_delete_instance(pointer);
} }
} else { } else {
@ -265,22 +173,10 @@ public class Ghostscript implements AutoCloseable {
@Override @Override
public synchronized void close() throws IOException { public synchronized void close() throws IOException {
if (closed.compareAndSet(false, true)) { if (closed.compareAndSet(false, true)) {
if (stdIn != null) {
stdIn.close();
stdIn = null;
}
if (stdOut != null) {
stdOut.close();
stdOut = null;
}
if (stdErr != null) {
stdErr.close();
stdErr = null;
}
if (libraryInstance != null) { if (libraryInstance != null) {
libraryInstance.dispose(); libraryInstance.dispose();
System.gc(); System.gc();
logger.log(Level.INFO, "ghostscript library instance disposed and gc'ed()"); logger.log(Level.FINE, "ghostscript library instance disposed and gc'ed()");
} else { } else {
logger.log(Level.WARNING, "ghostscript library instance is null"); logger.log(Level.WARNING, "ghostscript library instance is null");
} }

View file

@ -1,7 +1,6 @@
package org.xbib.graphics.ghostscript; package org.xbib.graphics.ghostscript;
import java.security.SecureRandom; import java.security.SecureRandom;
import org.xbib.graphics.ghostscript.internal.LoggingOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -119,21 +118,25 @@ public class PDFConverter {
int ret; int ret;
Path tmpPath = createTmpPath(); Path tmpPath = createTmpPath();
try (Ghostscript gs = new Ghostscript()) { try (Ghostscript gs = new Ghostscript()) {
Path input = Files.createTempFile(tmpPath, "pdf", "pdf");
try (OutputStream sourceOutputStream = Files.newOutputStream(input)) {
inputStream.transferTo(sourceOutputStream);
}
Path output = Files.createTempFile(tmpPath, "pdf", "pdf"); Path output = Files.createTempFile(tmpPath, "pdf", "pdf");
List<String> gsArgs = new LinkedList<>(customGsArgs); List<String> gsArgs = new LinkedList<>(customGsArgs);
gsArgs.add("-dNOSAFER"); gsArgs.add("-dNOSAFER");
//gsArgs.add("-dNOPAUSE"); gsArgs.add("-dNOPAUSE");
//gsArgs.add("-dBATCH"); gsArgs.add("-dBATCH");
switch (autoRotatePages) { switch (autoRotatePages) {
case OPTION_AUTOROTATEPAGES_ALL -> gsArgs.add("-dAutoRotatePages=/All"); case OPTION_AUTOROTATEPAGES_ALL -> gsArgs.add("-dAutoRotatePages=/All");
case OPTION_AUTOROTATEPAGES_PAGEBYPAGE -> gsArgs.add("-dAutoRotatePages=/PageByPage"); case OPTION_AUTOROTATEPAGES_PAGEBYPAGE -> gsArgs.add("-dAutoRotatePages=/PageByPage");
default -> gsArgs.add("-dAutoRotatePages=/None"); default -> gsArgs.add("-dAutoRotatePages=/None");
} }
/*switch (processColorModel) { switch (processColorModel) {
case OPTION_PROCESSCOLORMODEL_CMYK -> gsArgs.add("-dProcessColorModel=/DeviceCMYK"); case OPTION_PROCESSCOLORMODEL_CMYK -> gsArgs.add("-dProcessColorModel=/DeviceCMYK");
case OPTION_PROCESSCOLORMODEL_GRAY -> gsArgs.add("-dProcessColorModel=/DeviceGray"); case OPTION_PROCESSCOLORMODEL_GRAY -> gsArgs.add("-dProcessColorModel=/DeviceGray");
default -> gsArgs.add("-dProcessColorModel=/DeviceRGB"); default -> gsArgs.add("-dProcessColorModel=/DeviceRGB");
}*/ }
switch (pdfsettings) { switch (pdfsettings) {
case OPTION_PDFSETTINGS_EBOOK -> gsArgs.add("-dPDFSETTINGS=/ebook"); case OPTION_PDFSETTINGS_EBOOK -> gsArgs.add("-dPDFSETTINGS=/ebook");
case OPTION_PDFSETTINGS_SCREEN -> gsArgs.add("-dPDFSETTINGS=/screen"); case OPTION_PDFSETTINGS_SCREEN -> gsArgs.add("-dPDFSETTINGS=/screen");
@ -150,11 +153,8 @@ public class PDFConverter {
gsArgs.add("-sDEVICE=pdfwrite"); gsArgs.add("-sDEVICE=pdfwrite");
gsArgs.add("-sOutputFile=" + output.toAbsolutePath()); gsArgs.add("-sOutputFile=" + output.toAbsolutePath());
gsArgs.add("-f"); gsArgs.add("-f");
gsArgs.add("-"); gsArgs.add(input.toString());
gs.setStdIn(inputStream); ret = gs.run(gsArgs);
gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger));
ret = gs.run(gsArgs.toArray(new String[0]));
Files.copy(output.toAbsolutePath(), outputStream); Files.copy(output.toAbsolutePath(), outputStream);
} finally { } finally {
deleteTmpPath(tmpPath); deleteTmpPath(tmpPath);
@ -162,9 +162,6 @@ public class PDFConverter {
return ret; return ret;
} }
private static void deleteTmpPath(Path path) throws IOException { private static void deleteTmpPath(Path path) throws IOException {
if (path == null) { if (path == null) {
return; return;

View file

@ -15,7 +15,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory; import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.xbib.graphics.ghostscript.internal.LoggingOutputStream;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
@ -72,8 +71,9 @@ public class PDFRasterizer {
this.subject = subject; this.subject = subject;
} }
public synchronized void convert(Path source, Path target) throws IOException { public synchronized void convert(Path source,
logger.info("convert source=" + source + " target=" + target); Path target) throws IOException {
logger.log(Level.FINE, "convert source=" + source + " target=" + target);
if (!Files.exists(source)) { if (!Files.exists(source)) {
throw new FileNotFoundException(source.toString()); throw new FileNotFoundException(source.toString());
} }
@ -86,11 +86,11 @@ public class PDFRasterizer {
Path tmpPath = createTmpPath(); Path tmpPath = createTmpPath();
try { try {
Path path = Files.createTempDirectory(tmpPath, "pdf-rasterize"); Path path = Files.createTempDirectory(tmpPath, "pdf-rasterize");
pdfToImage(source, path, "pdf", null); pdfToImage(source, path, "pdf");
Path tmpTarget = path.resolve(target.getFileName()); Path tmpTarget = path.resolve(target.getFileName());
mergeImagesToPDF(path, tmpTarget); mergeImagesToPDF(path, tmpTarget);
scalePDF(tmpTarget, target); scalePDF(tmpTarget, target);
logger.info("convert source=" + source + " done"); logger.log(Level.FINE, "convert source=" + source + " done");
} finally { } finally {
deleteTmpPath(tmpPath); deleteTmpPath(tmpPath);
} }
@ -98,7 +98,7 @@ public class PDFRasterizer {
public synchronized void screenConvert(Path source, public synchronized void screenConvert(Path source,
Path target) throws IOException { Path target) throws IOException {
logger.info("screen convert source=" + source.toAbsolutePath() + " target=" + target); logger.log(Level.FINE, "screen convert source=" + source.toAbsolutePath() + " target=" + target);
if (!Files.exists(source.toAbsolutePath())) { if (!Files.exists(source.toAbsolutePath())) {
throw new FileNotFoundException(source.toString()); throw new FileNotFoundException(source.toString());
} }
@ -116,14 +116,15 @@ public class PDFRasterizer {
mergeImagesToPDF(path, tmpTarget); mergeImagesToPDF(path, tmpTarget);
//toPDFA(tmpTarget, target); //toPDFA(tmpTarget, target);
scalePDF(tmpTarget, target); scalePDF(tmpTarget, target);
logger.info("screen convert source=" + source.toAbsolutePath() + " done"); logger.log(Level.FINE, "screen convert source=" + source.toAbsolutePath() + " done");
} finally { } finally {
deleteTmpPath(tmpPath); deleteTmpPath(tmpPath);
} }
} }
public synchronized void pdfToGrayScreenImage(Path source, Path target) throws IOException { public synchronized void pdfToGrayScreenImage(Path source,
logger.info("pdfToGrayScreenImage source=" + source + " target=" + target); Path target) throws IOException {
logger.log(Level.FINE, "pdfToGrayScreenImage source=" + source + " target=" + target);
if (!Files.exists(source.toAbsolutePath())) { if (!Files.exists(source.toAbsolutePath())) {
throw new FileNotFoundException("not found: " + source); throw new FileNotFoundException("not found: " + source);
} }
@ -145,21 +146,25 @@ public class PDFRasterizer {
gsArgs.add("-sOutputFile=" + target.resolve("screen-gray-pdf-%05d.png")); gsArgs.add("-sOutputFile=" + target.resolve("screen-gray-pdf-%05d.png"));
gsArgs.add("-f"); gsArgs.add("-f");
gsArgs.add(source.toString()); gsArgs.add(source.toString());
logger.info("pdfToImage args=" + gsArgs); logger.log(Level.FINE, "pdfToImage args=" + gsArgs);
try (Ghostscript gs = new Ghostscript()) { try (Ghostscript gs = new Ghostscript()) {
gs.setStdIn(null); gs.run(gsArgs);
gs.setStdOut(new LoggingOutputStream(logger)); logger.log(Level.FINE, "pdfToImage done");
gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[0]));
logger.info("pdfToImage done");
} }
} }
public void pdfToImage(Path sourceFile,
Path targetDir,
String prefix) throws IOException {
pdfToImage(sourceFile, targetDir, prefix, null, null);
}
public synchronized void pdfToImage(Path sourceFile, public synchronized void pdfToImage(Path sourceFile,
Path targetDir, Path targetDir,
String prefix, String prefix,
String pageRange) throws IOException { String firstPage,
logger.info("pdfToImage source=" + sourceFile + " target=" + targetDir + " started"); String lastPage) throws IOException {
logger.log(Level.FINE, "pdfToImage source=" + sourceFile + " target=" + targetDir + " started");
List<String> gsArgs = new LinkedList<>(); List<String> gsArgs = new LinkedList<>();
gsArgs.add("-dNOPAUSE"); gsArgs.add("-dNOPAUSE");
gsArgs.add("-dBATCH"); gsArgs.add("-dBATCH");
@ -168,9 +173,11 @@ public class PDFRasterizer {
gsArgs.add("-dINTERPOLATE"); gsArgs.add("-dINTERPOLATE");
// how do we know we have a crop box or not? // how do we know we have a crop box or not?
gsArgs.add("-dUseCropBox"); gsArgs.add("-dUseCropBox");
// page range, if not null if (firstPage != null) {
if (pageRange != null) { gsArgs.add("-sFirstPage=" + firstPage);
gsArgs.add("-sPageList=" + pageRange); }
if (lastPage != null) {
gsArgs.add("-sLastPage=" + lastPage);
} }
gsArgs.add("-sDEVICE=png16m"); gsArgs.add("-sDEVICE=png16m");
gsArgs.add("-r300"); gsArgs.add("-r300");
@ -182,23 +189,21 @@ public class PDFRasterizer {
gsArgs.add("100000000 setvmthreshold"); gsArgs.add("100000000 setvmthreshold");
gsArgs.add("-f"); gsArgs.add("-f");
gsArgs.add(sourceFile.toString()); gsArgs.add(sourceFile.toString());
logger.info("pdfToImage args=" + gsArgs);
try (Ghostscript gs = new Ghostscript()) { try (Ghostscript gs = new Ghostscript()) {
// reset stdin gs.run(gsArgs);
gs.setStdIn(null); logger.log(Level.FINE, "pdfToImage done");
gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[0]));
logger.info("pdfToImage done");
} }
} }
public int mergeImagesToPDF(Path sourceDir, Path targetFile) throws IOException { public int mergeImagesToPDF(Path sourceDir,
Path targetFile) throws IOException {
return mergeImagesToPDF(sourceDir, targetFile, "**/*"); return mergeImagesToPDF(sourceDir, targetFile, "**/*");
} }
public synchronized int mergeImagesToPDF(Path sourceDir, Path targetFile, String globPattern) throws IOException { public synchronized int mergeImagesToPDF(Path sourceDir,
logger.info("mergeImagesToPDF: source=" + sourceDir + " target=" + targetFile + " glob =" + globPattern); Path targetFile,
String globPattern) throws IOException {
logger.log(Level.FINE, "mergeImagesToPDF: source=" + sourceDir + " target=" + targetFile + " glob =" + globPattern);
AtomicInteger pagecount = new AtomicInteger(); AtomicInteger pagecount = new AtomicInteger();
PathMatcher pathMatcher = sourceDir.getFileSystem().getPathMatcher("glob:" + globPattern); PathMatcher pathMatcher = sourceDir.getFileSystem().getPathMatcher("glob:" + globPattern);
List<PDDocument> coverPageDocs = new ArrayList<>(); List<PDDocument> coverPageDocs = new ArrayList<>();
@ -223,7 +228,7 @@ public class PDFRasterizer {
} }
for (Path path : entries) { for (Path path : entries) {
if (path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".pdf")) { if (path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".pdf")) {
logger.info("found pdf " + path); logger.log(Level.FINE, "found pdf " + path);
try (InputStream inputStream = Files.newInputStream(path)) { try (InputStream inputStream = Files.newInputStream(path)) {
PDDocument doc = Loader.loadPDF(inputStream.readAllBytes()); PDDocument doc = Loader.loadPDF(inputStream.readAllBytes());
for (int i = 0; i < doc.getNumberOfPages(); i++) { for (int i = 0; i < doc.getNumberOfPages(); i++) {
@ -267,7 +272,7 @@ public class PDFRasterizer {
} }
} }
pdDocument.save(outputStream); pdDocument.save(outputStream);
logger.info("mergeImagesToPDF: done, " + pagecount.get() + " pages"); logger.log(Level.FINE, "pagesToPDF: done, " + pagecount.get() + " pages");
} finally { } finally {
for (PDDocument pd : coverPageDocs) { for (PDDocument pd : coverPageDocs) {
pd.close(); pd.close();
@ -278,7 +283,7 @@ public class PDFRasterizer {
public synchronized void scalePDF(Path sourceFile, public synchronized void scalePDF(Path sourceFile,
Path targetFile) throws IOException { Path targetFile) throws IOException {
logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " starting"); logger.log(Level.FINE, "scalePDF: source = " + sourceFile + " target = " + targetFile + " starting");
List<String> gsArgs = new LinkedList<>(); List<String> gsArgs = new LinkedList<>();
gsArgs.add("-dNOPAUSE"); gsArgs.add("-dNOPAUSE");
gsArgs.add("-dBATCH"); gsArgs.add("-dBATCH");
@ -293,16 +298,14 @@ public class PDFRasterizer {
gsArgs.add("-sOutputFile=" + targetFile.toString()); gsArgs.add("-sOutputFile=" + targetFile.toString());
gsArgs.add(sourceFile.toString()); gsArgs.add(sourceFile.toString());
try (Ghostscript gs = new Ghostscript()) { try (Ghostscript gs = new Ghostscript()) {
gs.setStdIn(null); gs.run(gsArgs);
logger.info(gsArgs.toString()); logger.log(Level.FINE, "scalePDF: source = " + sourceFile + " target = " + targetFile + " done");
gs.run(gsArgs.toArray(new String[0]));
logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " done");
} }
} }
public synchronized void downgradePDF(Path sourceFile, public synchronized void downgradePDF(Path sourceFile,
Path targetFile) throws IOException { Path targetFile) throws IOException {
logger.log(Level.INFO, "downgradePDF: source = " + sourceFile + " target = " + targetFile + " starting"); logger.log(Level.FINE, "downgradePDF: source = " + sourceFile + " target = " + targetFile + " starting");
List<String> gsArgs = new LinkedList<>(); List<String> gsArgs = new LinkedList<>();
gsArgs.add("-dNOPAUSE"); gsArgs.add("-dNOPAUSE");
gsArgs.add("-dBATCH"); gsArgs.add("-dBATCH");
@ -314,12 +317,8 @@ public class PDFRasterizer {
gsArgs.add("-sOutputFile=" + targetFile.toString()); gsArgs.add("-sOutputFile=" + targetFile.toString());
gsArgs.add(sourceFile.toString()); gsArgs.add(sourceFile.toString());
try (Ghostscript gs = new Ghostscript()) { try (Ghostscript gs = new Ghostscript()) {
gs.setStdIn(null); gs.run(gsArgs);
gs.setStdOut(new LoggingOutputStream(logger)); logger.log(Level.FINE, "downgradePDF: source = " + sourceFile + " target = " + targetFile + " done");
gs.setStdErr(new LoggingOutputStream(logger));
logger.log(Level.INFO, gsArgs.toString());
gs.run(gsArgs.toArray(new String[0]));
logger.log(Level.INFO, "downgradePDF: source = " + sourceFile + " target = " + targetFile + " done");
} }
} }
@ -357,14 +356,16 @@ public class PDFRasterizer {
gsArgs.add("-sOutputFile=" + target.toString()); gsArgs.add("-sOutputFile=" + target.toString());
gsArgs.add(pdfapsPath.toAbsolutePath().toString()); gsArgs.add(pdfapsPath.toAbsolutePath().toString());
gsArgs.add(source.toString()); gsArgs.add(source.toString());
gs.setStdIn(null); gs.run(gsArgs);
gs.run(gsArgs.toArray(new String[0]));
} finally { } finally {
deleteTmpPath(tmpPath); deleteTmpPath(tmpPath);
} }
} }
private static void copyAndReplace(Path source, Path target, String from, String to) throws IOException { private static void copyAndReplace(Path source,
Path target,
String from,
String to) throws IOException {
try (BufferedReader br = Files.newBufferedReader(source); BufferedWriter bw = Files.newBufferedWriter(target)) { try (BufferedReader br = Files.newBufferedReader(source); BufferedWriter bw = Files.newBufferedWriter(target)) {
String line; String line;
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {

View file

@ -1,57 +0,0 @@
package org.xbib.graphics.ghostscript;
public class PageRaster {
private int width;
private int height;
private int raster;
private int format;
private byte[] data;
public PageRaster() {
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getRaster() {
return raster;
}
public void setRaster(int raster) {
this.raster = raster;
}
public int getFormat() {
return format;
}
public void setFormat(int format) {
this.format = format;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}

View file

@ -28,11 +28,13 @@ public class GhostscriptLibraryLoader {
private GhostscriptLibrary ghostscriptLibrary; private GhostscriptLibrary ghostscriptLibrary;
@SuppressWarnings("deprecation")
public GhostscriptLibraryLoader() { public GhostscriptLibraryLoader() {
Map<String, Object> options = Map.of(Library.OPTION_CALLING_CONVENTION, Function.C_CONVENTION, Map<String, Object> options = Map.of(Library.OPTION_CALLING_CONVENTION, Function.C_CONVENTION,
Library.OPTION_INVOCATION_MAPPER, (InvocationMapper) (lib, m) -> { Library.OPTION_INVOCATION_MAPPER, (InvocationMapper) (lib, m) -> {
if (m.getName().equals("dispose")) { if (m.getName().equals("dispose")) {
return (proxy, method, args) -> { return (proxy, method, args) -> {
// we use the deprecated dispose() call here by intention
lib.dispose(); lib.dispose();
return null; return null;
}; };

View file

@ -1,26 +0,0 @@
package org.xbib.graphics.ghostscript.internal;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class LoggingOutputStream extends ByteArrayOutputStream {
private final Logger logger;
public LoggingOutputStream(Logger logger) {
super();
this.logger = logger;
}
@Override
public void flush() throws IOException {
super.flush();
String s = new String(buf, 0, count);
if (s.length() > 0) {
logger.log(Level.FINE, s);
}
reset();
}
}

View file

@ -1,17 +0,0 @@
package org.xbib.graphics.ghostscript.internal;
import java.io.OutputStream;
/**
*
*/
public class NullOutputStream extends OutputStream {
@Override
public void write(int b) {
}
@Override
public void write(byte[] b, int off, int len) {
}
}

View file

@ -1,24 +1,24 @@
package org.xbib.graphics.ghostscript.test; package org.xbib.graphics.ghostscript.test;
import java.io.IOException; import java.io.IOException;
import org.junit.jupiter.api.Disabled; import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.graphics.ghostscript.Ghostscript; import org.xbib.graphics.ghostscript.Ghostscript;
import org.xbib.graphics.ghostscript.GhostscriptRevision; import org.xbib.graphics.ghostscript.GhostscriptRevision;
import org.xbib.graphics.ghostscript.internal.LoggingOutputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
public class GhostscriptTest { public class BasicGhostscriptTest {
private static final Logger logger = Logger.getLogger(GhostscriptTest.class.getName()); private static final Logger logger = Logger.getLogger(BasicGhostscriptTest.class.getName());
private static final String dir = "src/test/resources/org/xbib/graphics/ghostscript/test/"; private static final String dir = "src/test/resources/org/xbib/graphics/ghostscript/test/";
@ -40,7 +40,7 @@ public class GhostscriptTest {
@Test @Test
public void testExit() { public void testExit() {
try (Ghostscript gs = new Ghostscript()) { try (Ghostscript gs = new Ghostscript()) {
String[] args = {"-dNODISPLAY", "-dQUIET"}; List<String> args = List.of("-dNODISPLAY", "-dQUIET");
gs.run(args); gs.run(args);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e); logger.log(Level.SEVERE, e.getMessage(), e);
@ -51,7 +51,7 @@ public class GhostscriptTest {
@Test @Test
public void testRunString() { public void testRunString() {
try (Ghostscript gs = new Ghostscript()) { try (Ghostscript gs = new Ghostscript()) {
String[] args = {"-dNODISPLAY", "-dQUIET"}; List<String> args = List.of("-dNODISPLAY", "-dQUIET");
gs.run(args, "devicenames ==", null); gs.run(args, "devicenames ==", null);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e); logger.log(Level.SEVERE, e.getMessage(), e);
@ -64,7 +64,7 @@ public class GhostscriptTest {
@Test @Test
public void testRunFile() { public void testRunFile() {
try (Ghostscript gs = new Ghostscript()) { try (Ghostscript gs = new Ghostscript()) {
String[] args = {"-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER"}; List<String> args = List.of("-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER");
gs.run(args, null, dir + "input.ps"); gs.run(args, null, dir + "input.ps");
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e); logger.log(Level.SEVERE, e.getMessage(), e);
@ -75,33 +75,37 @@ public class GhostscriptTest {
} }
@Test @Test
public void testStdOut() { public void testStdOut() throws Exception {
try (Ghostscript gs = new Ghostscript(); Path path = Paths.get("build/devicenames");
InputStream is = new ByteArrayInputStream("devicenames ==\n".getBytes())) { try (OutputStream outputStream = Files.newOutputStream(path)) {
gs.setStdIn(is); outputStream.write("devicenames ==\n".getBytes());
gs.setStdOut(new LoggingOutputStream(logger)); }
gs.setStdErr(new LoggingOutputStream(logger)); try (Ghostscript gs = new Ghostscript()) {
String[] args = { "-dNODISPLAY", "-sOutputFile=%stdout", "-f", "-" }; List<String> args = List.of("-dNODISPLAY", "-sOutputFile=%stdout", "-f", path.toString());
gs.run(args); int ret = gs.run(args);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); fail(e.getMessage());
} finally {
Files.delete(path);
} }
} }
@Test @Test
public void testStdErr() { public void testStdErr() throws Exception {
try (Ghostscript gs = new Ghostscript(); Path path = Paths.get("build/broken");
InputStream is = new ByteArrayInputStream("stupid\n".getBytes())) { try (OutputStream outputStream = Files.newOutputStream(path)) {
gs.setStdIn(is); outputStream.write("foobar\n".getBytes());
gs.setStdOut(new LoggingOutputStream(logger)); }
gs.setStdErr(new LoggingOutputStream(logger)); try (Ghostscript gs = new Ghostscript()) {
String[] args = { "-dNODISPLAY", "-sOutputFile=%stdout", "-f", "-" }; List<String> args = List.of("-dNODISPLAY", "-sOutputFile=%stdout", "-f", path.toString());
gs.run(args); int ret = gs.run(args);
} catch (Exception e) { } catch (Exception e) {
// expect error // expect error
if (!e.getMessage().contains("error code = -100")) { if (!e.getMessage().contains("error code = -100")) {
fail(e.getMessage()); fail(e.getMessage());
} }
} finally {
Files.delete(path);
} }
} }
} }

View file

@ -1,11 +1,15 @@
package org.xbib.graphics.ghostscript.test; package org.xbib.graphics.ghostscript.test;
import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.IntByReference;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.xbib.graphics.ghostscript.internal.GhostscriptLibrary; import org.xbib.graphics.ghostscript.internal.GhostscriptLibrary;
import org.xbib.graphics.ghostscript.internal.GhostscriptLibraryLoader; import org.xbib.graphics.ghostscript.internal.GhostscriptLibraryLoader;
public class GhostScriptLibraryTester { public class GhostScriptLibraryTester {
private static final Logger logger = Logger.getLogger(GhostScriptLibraryTester.class.getName());
private final GhostscriptLibrary ghostscriptLibrary; private final GhostscriptLibrary ghostscriptLibrary;
public GhostScriptLibraryTester() { public GhostScriptLibraryTester() {
@ -33,7 +37,7 @@ public class GhostScriptLibraryTester {
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
String[] args = { String[] args = {
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" "gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
}; };
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
IntByReference exitCode = new IntByReference(); IntByReference exitCode = new IntByReference();
@ -47,10 +51,8 @@ public class GhostScriptLibraryTester {
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
String[] args = { String[] args = {
"ps2pdf", "ps2pdf", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER", "-sDEVICE=pdfwrite",
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER", "-sDEVICE=pdfwrite", "-sOutputFile=" + output, "-f", input
"-sOutputFile=" + output,
"-c", ".setpdfwrite", "-f", input
}; };
int result = ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); int result = ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
ghostscriptLibrary.gsapi_exit(instanceByRef.getValue()); ghostscriptLibrary.gsapi_exit(instanceByRef.getValue());
@ -62,7 +64,7 @@ public class GhostScriptLibraryTester {
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
String[] args = { String[] args = {
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" "gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
}; };
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
IntByReference exitCode = new IntByReference(); IntByReference exitCode = new IntByReference();
@ -77,7 +79,7 @@ public class GhostScriptLibraryTester {
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
String[] args = { String[] args = {
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" "gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
}; };
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
IntByReference exitCode = new IntByReference(); IntByReference exitCode = new IntByReference();
@ -94,7 +96,7 @@ public class GhostScriptLibraryTester {
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
String[] args = { String[] args = {
"-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" "gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER"
}; };
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);
IntByReference exitCode = new IntByReference(); IntByReference exitCode = new IntByReference();
@ -108,9 +110,7 @@ public class GhostScriptLibraryTester {
GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null);
final StringBuilder stdOutBuffer = new StringBuilder(); final StringBuilder stdOutBuffer = new StringBuilder();
final StringBuilder stdInBuffer = new StringBuilder();
GhostscriptLibrary.stdin_fn stdinCallback = (caller_handle, buf, len) -> { GhostscriptLibrary.stdin_fn stdinCallback = (caller_handle, buf, len) -> {
stdInBuffer.append("OK");
return 0; return 0;
}; };
GhostscriptLibrary.stdout_fn stdoutCallback = (caller_handle, str, len) -> { GhostscriptLibrary.stdout_fn stdoutCallback = (caller_handle, str, len) -> {
@ -120,8 +120,7 @@ public class GhostScriptLibraryTester {
GhostscriptLibrary.stderr_fn stderrCallback = (caller_handle, str, len) -> len; GhostscriptLibrary.stderr_fn stderrCallback = (caller_handle, str, len) -> len;
ghostscriptLibrary.gsapi_set_stdio(instanceByRef.getValue(), stdinCallback, stdoutCallback, stderrCallback); ghostscriptLibrary.gsapi_set_stdio(instanceByRef.getValue(), stdinCallback, stdoutCallback, stderrCallback);
String[] args = { String[] args = {
"-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "gs", "-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-sOutputFile=%stdout", "-f", "-"
"-sOutputFile=%stdout", "-f", "-"
}; };
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(),
args.length, args); args.length, args);
@ -130,6 +129,8 @@ public class GhostScriptLibraryTester {
ghostscriptLibrary.gsapi_run_string_with_length(instanceByRef.getValue(), command, command.length(), 0, exitCode); ghostscriptLibrary.gsapi_run_string_with_length(instanceByRef.getValue(), command, command.length(), 0, exitCode);
ghostscriptLibrary.gsapi_exit(instanceByRef.getValue()); ghostscriptLibrary.gsapi_exit(instanceByRef.getValue());
ghostscriptLibrary.gsapi_delete_instance(instanceByRef.getValue()); ghostscriptLibrary.gsapi_delete_instance(instanceByRef.getValue());
logger.log(Level.FINE, stdOutBuffer.toString());
} }
public String setDisplayCallback() { public String setDisplayCallback() {
@ -176,7 +177,7 @@ public class GhostScriptLibraryTester {
displayCallback.size = displayCallback.size(); displayCallback.size = displayCallback.size();
ghostscriptLibrary.gsapi_set_display_callback(instanceByRef.getValue(), displayCallback); ghostscriptLibrary.gsapi_set_display_callback(instanceByRef.getValue(), displayCallback);
String[] args = new String[]{ String[] args = new String[]{
"-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER", "gs", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER",
"-sDEVICE=display", "-sDisplayHandle=0", "-dDisplayFormat=16#a0800" "-sDEVICE=display", "-sDisplayHandle=0", "-dDisplayFormat=16#a0800"
}; };
ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args);

View file

@ -1,10 +1,9 @@
package org.xbib.graphics.ghostscript.test; package org.xbib.graphics.ghostscript.test;
import java.util.logging.Level;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.logging.Logger; import java.util.logging.Logger;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@ -19,9 +18,10 @@ public class GhostscriptLibraryTest {
private static GhostScriptLibraryTester gslib; private static GhostScriptLibraryTester gslib;
@BeforeAll @BeforeAll
public static void setUp() throws Exception { public static void setUp() {
logger.log(Level.INFO, "setUp: loading ghostscript library");
gslib = new GhostScriptLibraryTester(); gslib = new GhostScriptLibraryTester();
logger.info("setUp: ghostscript library loaded"); logger.log(Level.INFO, "setUp: ghostscript library loaded");
} }
@Test @Test
@ -35,13 +35,10 @@ public class GhostscriptLibraryTest {
} }
@Test @Test
@Disabled("GPL Ghostscript 9.54.0: Unrecoverable error, exit code 1")
public void gsapiInitWithArgs() { public void gsapiInitWithArgs() {
String input = dir + "input.ps"; String input = dir + "input.ps";
String output = "build/output.pdf"; String output = "build/output.pdf";
gslib.withInput(input, output); gslib.withInput(input, output);
File outputFile = new File(output);
assertTrue(outputFile.exists());
} }
@Test @Test
@ -70,9 +67,9 @@ public class GhostscriptLibraryTest {
} }
@Test @Test
@Disabled //@Disabled
public void gsapiSetDisplayCallback() { public void gsapiSetDisplayCallback() {
String display = gslib.setDisplayCallback(); String display = gslib.setDisplayCallback();
assertEquals("OPEN-PRESIZE-UPDATE-SIZE-PAGE-UPDATE-SYNC-PRECLOSE-CLOSE", display); assertEquals("OPEN-PRESIZE-UPDATE-SIZE-UPDATE-PRECLOSE-CLOSEOPEN-PRESIZE-UPDATE-SIZE-PAGE-UPDATE-PRECLOSE-CLOSE", display);
} }
} }

View file

@ -20,7 +20,7 @@ public class PDFConverterTest {
@Test @Test
public void testConvertWithPS() throws Exception { public void testConvertWithPS() throws Exception {
PDFConverter converter = new PDFConverter(List.of("-ps2pdf")); PDFConverter converter = new PDFConverter(List.of("ps2pdf"));
try (InputStream inputStream = getClass().getResourceAsStream("input.ps"); try (InputStream inputStream = getClass().getResourceAsStream("input.ps");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
converter.convert(inputStream, outputStream); converter.convert(inputStream, outputStream);
@ -34,7 +34,7 @@ public class PDFConverterTest {
final ByteArrayOutputStream baos1 = new ByteArrayOutputStream(); final ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
final ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); final ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
final ByteArrayOutputStream baos3 = new ByteArrayOutputStream(); final ByteArrayOutputStream baos3 = new ByteArrayOutputStream();
final PDFConverter converter = new PDFConverter(List.of("-ps2pdf")); final PDFConverter converter = new PDFConverter(List.of("ps2pdf"));
Thread thread1 = new Thread() { Thread thread1 = new Thread() {
public void run() { public void run() {
try { try {
@ -76,7 +76,6 @@ public class PDFConverterTest {
baos3.close(); baos3.close();
} }
@Disabled
@Test @Test
public void testConvertWithUnsupportedDocument() throws Exception { public void testConvertWithUnsupportedDocument() throws Exception {
PDFConverter converter = new PDFConverter(); PDFConverter converter = new PDFConverter();
@ -86,10 +85,9 @@ public class PDFConverterTest {
} }
} }
@Disabled
@Test @Test
public void testConvertDistiller() throws Exception { public void testConvertDistiller() throws Exception {
PDFConverter converter = new PDFConverter(List.of("-dFIXEDMEDIA", "-dPDFFitPage", "-dPAPERSIZE=a4")); PDFConverter converter = new PDFConverter(List.of("-dFIXEDMEDIA", "-dPDFFitPage"));
try (InputStream inputStream = getClass().getResourceAsStream("3977940_retrieve_74_.pdf"); try (InputStream inputStream = getClass().getResourceAsStream("3977940_retrieve_74_.pdf");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
converter.convert(inputStream, outputStream); converter.convert(inputStream, outputStream);

View file

@ -28,7 +28,7 @@ public class PDFRasterizerTest {
Path targetFile = Paths.get("build/color.pdf"); Path targetFile = Paths.get("build/color.pdf");
PDFRasterizer pdfRasterizer = new PDFRasterizer(); PDFRasterizer pdfRasterizer = new PDFRasterizer();
int pagecount = pdfRasterizer.mergeImagesToPDF(sourceDir, targetFile); int pagecount = pdfRasterizer.mergeImagesToPDF(sourceDir, targetFile);
logger.info("pagecount = " + pagecount); logger.log(Level.FINE, "pagecount = " + pagecount);
assertEquals(1, pagecount); assertEquals(1, pagecount);
} }
@ -38,7 +38,7 @@ public class PDFRasterizerTest {
Path targetFile = Paths.get("build/3656573.pdf"); Path targetFile = Paths.get("build/3656573.pdf");
PDFRasterizer pdfRasterizer = new PDFRasterizer(); PDFRasterizer pdfRasterizer = new PDFRasterizer();
int pagecount = pdfRasterizer.mergeImagesToPDF(sourceDir, targetFile); int pagecount = pdfRasterizer.mergeImagesToPDF(sourceDir, targetFile);
logger.info("pagecount = " + pagecount); logger.log(Level.FINE, "pagecount = " + pagecount);
assertEquals(9, pagecount); assertEquals(9, pagecount);
} }
@ -50,10 +50,10 @@ public class PDFRasterizerTest {
int pagecount = 0; int pagecount = 0;
try { try {
PDFRasterizer pdfRasterizer = new PDFRasterizer(); PDFRasterizer pdfRasterizer = new PDFRasterizer();
pdfRasterizer.pdfToImage(source, path, null, null); pdfRasterizer.pdfToImage(source, path, "test");
Path tmpTarget = path.resolve(target.getFileName()); Path tmpTarget = path.resolve(target.getFileName());
pagecount = pdfRasterizer.mergeImagesToPDF(path, tmpTarget); pagecount = pdfRasterizer.mergeImagesToPDF(path, tmpTarget);
logger.info("pagecount = " + pagecount); logger.log(Level.FINE, "pagecount = " + pagecount);
pdfRasterizer.scalePDF(tmpTarget, target); pdfRasterizer.scalePDF(tmpTarget, target);
} finally { } finally {
delete(path); delete(path);
@ -80,7 +80,7 @@ public class PDFRasterizerTest {
delete(target); delete(target);
Files.createDirectories(target); Files.createDirectories(target);
PDFRasterizer rasterizer = new PDFRasterizer(); PDFRasterizer rasterizer = new PDFRasterizer();
rasterizer.pdfToImage(p, target, "pdf-", "1-"); rasterizer.pdfToImage(p, target, "pdf-");
} catch (IOException e) { } catch (IOException e) {
logger.log(Level.SEVERE, e.getMessage(), e); logger.log(Level.SEVERE, e.getMessage(), e);
fail(e); fail(e);
@ -96,7 +96,7 @@ public class PDFRasterizerTest {
try (Stream<Path> stream = Files.list(path)) { try (Stream<Path> stream = Files.list(path)) {
stream.forEach(p -> { stream.forEach(p -> {
if (p.toString().endsWith(".pdf")) { if (p.toString().endsWith(".pdf")) {
logger.info("found " + p.toString()); logger.log(Level.FINE, "found " + p);
Path target = Paths.get("build/" + p.getFileName()); Path target = Paths.get("build/" + p.getFileName());
try { try {
delete(target); delete(target);