diff --git a/gradle.properties b/gradle.properties index edd4de7..6bf05b0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ group = org.xbib.graphics name = graphics -version = 5.4.0 +version = 5.5.0 diff --git a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/Ghostscript.java b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/Ghostscript.java index d92c162..bbdaca8 100644 --- a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/Ghostscript.java +++ b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/Ghostscript.java @@ -2,23 +2,20 @@ package org.xbib.graphics.ghostscript; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; +import java.util.LinkedList; +import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import org.xbib.graphics.ghostscript.internal.ErrorCodes; import org.xbib.graphics.ghostscript.internal.GhostscriptLibrary; 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.InputStream; -import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.LocalDate; import java.time.format.DateTimeFormatter; -import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; @@ -33,21 +30,12 @@ public class Ghostscript implements AutoCloseable { private final GhostscriptLibrary libraryInstance; - private InputStream stdIn; - - private OutputStream stdOut; - - private OutputStream stdErr; - private final AtomicBoolean closed; public Ghostscript() throws IOException { prepareTmp(); GhostscriptLibraryLoader libraryLoader = new GhostscriptLibraryLoader(); - this.libraryInstance = libraryLoader.getGhostscriptLibrary(); - Objects.requireNonNull(this.libraryInstance); - this.stdOut = new LoggingOutputStream(logger); - this.stdErr = new LoggingOutputStream(logger); + this.libraryInstance = Objects.requireNonNull(libraryLoader.getGhostscriptLibrary(), "library instance must not be null"); this.closed = new AtomicBoolean(false); } @@ -68,62 +56,7 @@ public class Ghostscript implements AutoCloseable { return result; } - /** - * 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 { + public synchronized int run(List args) throws IOException { return run(args, null, null); } @@ -136,9 +69,15 @@ public class Ghostscript implements AutoCloseable { * @return the ghostscript return code; * @throws IOException if initialize fails */ - public synchronized int run(String[] args, + public synchronized int run(List args, String runString, String fileName) throws IOException { + Objects.requireNonNull(args); + List 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; int ret = 0; boolean quit = false; @@ -149,47 +88,16 @@ public class Ghostscript implements AutoCloseable { nativeInstanceByRef = null; 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(); - GhostscriptLibrary.stdin_fn stdinCallback = null; - if (getStdIn() != null) { - stdinCallback = (caller_handle, buf, len) -> { - String encoding = System.getProperty(ENCODING_PARAMETER, "UTF-8"); - 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); - } + // always 0, we never use stdin + GhostscriptLibrary.stdin_fn stdinCallback = (caller_handle, buf, len) -> 0; + GhostscriptLibrary.stdout_fn stdoutCallback = (caller_handle, str, len) -> { + logger.log(Level.FINE, str.substring(0, len)); return len; }; - GhostscriptLibrary.stderr_fn stderrCallback; - if (getStdErr() == null) { - 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); - } + GhostscriptLibrary.stderr_fn stderrCallback = (caller_handle, str, len) -> { + logger.log(Level.FINE, str.substring(0, len)); return len; }; logger.log(Level.FINE, "setting gsapi_set_stdio"); @@ -197,8 +105,8 @@ public class Ghostscript implements AutoCloseable { if (ret != 0) { 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")); - ret = libraryInstance.gsapi_init_with_args(pointer, args != null ? args.length : 0, args); + logger.log(Level.FINE, "gsapi_init_with_args = " + fullArgList); + 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); if (ret == ErrorCodes.gs_error_Quit) { quit = true; @@ -246,12 +154,12 @@ public class Ghostscript implements AutoCloseable { Pointer pointer = nativeInstanceByRef.getValue(); if (pointer != null) { 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); if (ret != 0) { 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); } } else { @@ -265,22 +173,10 @@ public class Ghostscript implements AutoCloseable { @Override public synchronized void close() throws IOException { 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) { libraryInstance.dispose(); 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 { logger.log(Level.WARNING, "ghostscript library instance is null"); } diff --git a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PDFConverter.java b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PDFConverter.java index f8c615c..7230ad4 100644 --- a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PDFConverter.java +++ b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PDFConverter.java @@ -1,7 +1,6 @@ package org.xbib.graphics.ghostscript; import java.security.SecureRandom; -import org.xbib.graphics.ghostscript.internal.LoggingOutputStream; import java.io.IOException; import java.io.InputStream; @@ -119,21 +118,25 @@ public class PDFConverter { int ret; Path tmpPath = createTmpPath(); 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"); List gsArgs = new LinkedList<>(customGsArgs); gsArgs.add("-dNOSAFER"); - //gsArgs.add("-dNOPAUSE"); - //gsArgs.add("-dBATCH"); + gsArgs.add("-dNOPAUSE"); + gsArgs.add("-dBATCH"); switch (autoRotatePages) { case OPTION_AUTOROTATEPAGES_ALL -> gsArgs.add("-dAutoRotatePages=/All"); case OPTION_AUTOROTATEPAGES_PAGEBYPAGE -> gsArgs.add("-dAutoRotatePages=/PageByPage"); default -> gsArgs.add("-dAutoRotatePages=/None"); } - /*switch (processColorModel) { + switch (processColorModel) { case OPTION_PROCESSCOLORMODEL_CMYK -> gsArgs.add("-dProcessColorModel=/DeviceCMYK"); case OPTION_PROCESSCOLORMODEL_GRAY -> gsArgs.add("-dProcessColorModel=/DeviceGray"); default -> gsArgs.add("-dProcessColorModel=/DeviceRGB"); - }*/ + } switch (pdfsettings) { case OPTION_PDFSETTINGS_EBOOK -> gsArgs.add("-dPDFSETTINGS=/ebook"); case OPTION_PDFSETTINGS_SCREEN -> gsArgs.add("-dPDFSETTINGS=/screen"); @@ -150,11 +153,8 @@ public class PDFConverter { gsArgs.add("-sDEVICE=pdfwrite"); gsArgs.add("-sOutputFile=" + output.toAbsolutePath()); gsArgs.add("-f"); - gsArgs.add("-"); - gs.setStdIn(inputStream); - gs.setStdOut(new LoggingOutputStream(logger)); - gs.setStdErr(new LoggingOutputStream(logger)); - ret = gs.run(gsArgs.toArray(new String[0])); + gsArgs.add(input.toString()); + ret = gs.run(gsArgs); Files.copy(output.toAbsolutePath(), outputStream); } finally { deleteTmpPath(tmpPath); @@ -162,9 +162,6 @@ public class PDFConverter { return ret; } - - - private static void deleteTmpPath(Path path) throws IOException { if (path == null) { return; diff --git a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PDFRasterizer.java b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PDFRasterizer.java index c6569bd..49a2539 100644 --- a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PDFRasterizer.java +++ b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PDFRasterizer.java @@ -15,7 +15,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; -import org.xbib.graphics.ghostscript.internal.LoggingOutputStream; import java.awt.image.BufferedImage; import java.io.BufferedOutputStream; @@ -72,8 +71,9 @@ public class PDFRasterizer { this.subject = subject; } - public synchronized void convert(Path source, Path target) throws IOException { - logger.info("convert source=" + source + " target=" + target); + public synchronized void convert(Path source, + Path target) throws IOException { + logger.log(Level.FINE, "convert source=" + source + " target=" + target); if (!Files.exists(source)) { throw new FileNotFoundException(source.toString()); } @@ -86,11 +86,11 @@ public class PDFRasterizer { Path tmpPath = createTmpPath(); try { Path path = Files.createTempDirectory(tmpPath, "pdf-rasterize"); - pdfToImage(source, path, "pdf", null); + pdfToImage(source, path, "pdf"); Path tmpTarget = path.resolve(target.getFileName()); mergeImagesToPDF(path, tmpTarget); scalePDF(tmpTarget, target); - logger.info("convert source=" + source + " done"); + logger.log(Level.FINE, "convert source=" + source + " done"); } finally { deleteTmpPath(tmpPath); } @@ -98,7 +98,7 @@ public class PDFRasterizer { public synchronized void screenConvert(Path source, 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())) { throw new FileNotFoundException(source.toString()); } @@ -116,14 +116,15 @@ public class PDFRasterizer { mergeImagesToPDF(path, tmpTarget); //toPDFA(tmpTarget, target); scalePDF(tmpTarget, target); - logger.info("screen convert source=" + source.toAbsolutePath() + " done"); + logger.log(Level.FINE, "screen convert source=" + source.toAbsolutePath() + " done"); } finally { deleteTmpPath(tmpPath); } } - public synchronized void pdfToGrayScreenImage(Path source, Path target) throws IOException { - logger.info("pdfToGrayScreenImage source=" + source + " target=" + target); + public synchronized void pdfToGrayScreenImage(Path source, + Path target) throws IOException { + logger.log(Level.FINE, "pdfToGrayScreenImage source=" + source + " target=" + target); if (!Files.exists(source.toAbsolutePath())) { 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("-f"); gsArgs.add(source.toString()); - logger.info("pdfToImage args=" + gsArgs); + logger.log(Level.FINE, "pdfToImage args=" + gsArgs); try (Ghostscript gs = new Ghostscript()) { - gs.setStdIn(null); - gs.setStdOut(new LoggingOutputStream(logger)); - gs.setStdErr(new LoggingOutputStream(logger)); - gs.run(gsArgs.toArray(new String[0])); - logger.info("pdfToImage done"); + gs.run(gsArgs); + logger.log(Level.FINE, "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, Path targetDir, String prefix, - String pageRange) throws IOException { - logger.info("pdfToImage source=" + sourceFile + " target=" + targetDir + " started"); + String firstPage, + String lastPage) throws IOException { + logger.log(Level.FINE, "pdfToImage source=" + sourceFile + " target=" + targetDir + " started"); List gsArgs = new LinkedList<>(); gsArgs.add("-dNOPAUSE"); gsArgs.add("-dBATCH"); @@ -168,9 +173,11 @@ public class PDFRasterizer { gsArgs.add("-dINTERPOLATE"); // how do we know we have a crop box or not? gsArgs.add("-dUseCropBox"); - // page range, if not null - if (pageRange != null) { - gsArgs.add("-sPageList=" + pageRange); + if (firstPage != null) { + gsArgs.add("-sFirstPage=" + firstPage); + } + if (lastPage != null) { + gsArgs.add("-sLastPage=" + lastPage); } gsArgs.add("-sDEVICE=png16m"); gsArgs.add("-r300"); @@ -182,23 +189,21 @@ public class PDFRasterizer { gsArgs.add("100000000 setvmthreshold"); gsArgs.add("-f"); gsArgs.add(sourceFile.toString()); - logger.info("pdfToImage args=" + gsArgs); try (Ghostscript gs = new Ghostscript()) { - // reset stdin - gs.setStdIn(null); - gs.setStdOut(new LoggingOutputStream(logger)); - gs.setStdErr(new LoggingOutputStream(logger)); - gs.run(gsArgs.toArray(new String[0])); - logger.info("pdfToImage done"); + gs.run(gsArgs); + logger.log(Level.FINE, "pdfToImage done"); } } - public int mergeImagesToPDF(Path sourceDir, Path targetFile) throws IOException { + public int mergeImagesToPDF(Path sourceDir, + Path targetFile) throws IOException { return mergeImagesToPDF(sourceDir, targetFile, "**/*"); } - public synchronized int mergeImagesToPDF(Path sourceDir, Path targetFile, String globPattern) throws IOException { - logger.info("mergeImagesToPDF: source=" + sourceDir + " target=" + targetFile + " glob =" + globPattern); + public synchronized int mergeImagesToPDF(Path sourceDir, + Path targetFile, + String globPattern) throws IOException { + logger.log(Level.FINE, "mergeImagesToPDF: source=" + sourceDir + " target=" + targetFile + " glob =" + globPattern); AtomicInteger pagecount = new AtomicInteger(); PathMatcher pathMatcher = sourceDir.getFileSystem().getPathMatcher("glob:" + globPattern); List coverPageDocs = new ArrayList<>(); @@ -223,7 +228,7 @@ public class PDFRasterizer { } for (Path path : entries) { 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)) { PDDocument doc = Loader.loadPDF(inputStream.readAllBytes()); for (int i = 0; i < doc.getNumberOfPages(); i++) { @@ -267,7 +272,7 @@ public class PDFRasterizer { } } pdDocument.save(outputStream); - logger.info("mergeImagesToPDF: done, " + pagecount.get() + " pages"); + logger.log(Level.FINE, "pagesToPDF: done, " + pagecount.get() + " pages"); } finally { for (PDDocument pd : coverPageDocs) { pd.close(); @@ -278,7 +283,7 @@ public class PDFRasterizer { public synchronized void scalePDF(Path sourceFile, Path targetFile) throws IOException { - logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " starting"); + logger.log(Level.FINE, "scalePDF: source = " + sourceFile + " target = " + targetFile + " starting"); List gsArgs = new LinkedList<>(); gsArgs.add("-dNOPAUSE"); gsArgs.add("-dBATCH"); @@ -293,16 +298,14 @@ public class PDFRasterizer { gsArgs.add("-sOutputFile=" + targetFile.toString()); gsArgs.add(sourceFile.toString()); try (Ghostscript gs = new Ghostscript()) { - gs.setStdIn(null); - logger.info(gsArgs.toString()); - gs.run(gsArgs.toArray(new String[0])); - logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " done"); + gs.run(gsArgs); + logger.log(Level.FINE, "scalePDF: source = " + sourceFile + " target = " + targetFile + " done"); } } public synchronized void downgradePDF(Path sourceFile, 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 gsArgs = new LinkedList<>(); gsArgs.add("-dNOPAUSE"); gsArgs.add("-dBATCH"); @@ -314,12 +317,8 @@ public class PDFRasterizer { gsArgs.add("-sOutputFile=" + targetFile.toString()); gsArgs.add(sourceFile.toString()); try (Ghostscript gs = new Ghostscript()) { - gs.setStdIn(null); - gs.setStdOut(new LoggingOutputStream(logger)); - 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"); + gs.run(gsArgs); + logger.log(Level.FINE, "downgradePDF: source = " + sourceFile + " target = " + targetFile + " done"); } } @@ -357,14 +356,16 @@ public class PDFRasterizer { gsArgs.add("-sOutputFile=" + target.toString()); gsArgs.add(pdfapsPath.toAbsolutePath().toString()); gsArgs.add(source.toString()); - gs.setStdIn(null); - gs.run(gsArgs.toArray(new String[0])); + gs.run(gsArgs); } finally { 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)) { String line; while ((line = br.readLine()) != null) { diff --git a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PageRaster.java b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PageRaster.java deleted file mode 100644 index 35523c3..0000000 --- a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/PageRaster.java +++ /dev/null @@ -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; - } -} diff --git a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/GhostscriptLibraryLoader.java b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/GhostscriptLibraryLoader.java index 9fc67ec..66717d2 100644 --- a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/GhostscriptLibraryLoader.java +++ b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/GhostscriptLibraryLoader.java @@ -28,11 +28,13 @@ public class GhostscriptLibraryLoader { private GhostscriptLibrary ghostscriptLibrary; + @SuppressWarnings("deprecation") public GhostscriptLibraryLoader() { Map options = Map.of(Library.OPTION_CALLING_CONVENTION, Function.C_CONVENTION, Library.OPTION_INVOCATION_MAPPER, (InvocationMapper) (lib, m) -> { if (m.getName().equals("dispose")) { return (proxy, method, args) -> { + // we use the deprecated dispose() call here by intention lib.dispose(); return null; }; diff --git a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/LoggingOutputStream.java b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/LoggingOutputStream.java deleted file mode 100644 index 5473072..0000000 --- a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/LoggingOutputStream.java +++ /dev/null @@ -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(); - } -} diff --git a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/NullOutputStream.java b/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/NullOutputStream.java deleted file mode 100644 index 8798555..0000000 --- a/graphics-ghostscript/src/main/java/org/xbib/graphics/ghostscript/internal/NullOutputStream.java +++ /dev/null @@ -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) { - } -} diff --git a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostscriptTest.java b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/BasicGhostscriptTest.java similarity index 62% rename from graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostscriptTest.java rename to graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/BasicGhostscriptTest.java index 2e8ba0e..4a51aa6 100644 --- a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostscriptTest.java +++ b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/BasicGhostscriptTest.java @@ -1,24 +1,24 @@ package org.xbib.graphics.ghostscript.test; 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.xbib.graphics.ghostscript.Ghostscript; 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.Logger; import static org.junit.jupiter.api.Assertions.assertNotNull; 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/"; @@ -40,7 +40,7 @@ public class GhostscriptTest { @Test public void testExit() { try (Ghostscript gs = new Ghostscript()) { - String[] args = {"-dNODISPLAY", "-dQUIET"}; + List args = List.of("-dNODISPLAY", "-dQUIET"); gs.run(args); } catch (Exception e) { logger.log(Level.SEVERE, e.getMessage(), e); @@ -51,7 +51,7 @@ public class GhostscriptTest { @Test public void testRunString() { try (Ghostscript gs = new Ghostscript()) { - String[] args = {"-dNODISPLAY", "-dQUIET"}; + List args = List.of("-dNODISPLAY", "-dQUIET"); gs.run(args, "devicenames ==", null); } catch (Exception e) { logger.log(Level.SEVERE, e.getMessage(), e); @@ -64,7 +64,7 @@ public class GhostscriptTest { @Test public void testRunFile() { try (Ghostscript gs = new Ghostscript()) { - String[] args = {"-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER"}; + List args = List.of("-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER"); gs.run(args, null, dir + "input.ps"); } catch (Exception e) { logger.log(Level.SEVERE, e.getMessage(), e); @@ -75,33 +75,37 @@ public class GhostscriptTest { } @Test - public void testStdOut() { - try (Ghostscript gs = new Ghostscript(); - InputStream is = new ByteArrayInputStream("devicenames ==\n".getBytes())) { - gs.setStdIn(is); - gs.setStdOut(new LoggingOutputStream(logger)); - gs.setStdErr(new LoggingOutputStream(logger)); - String[] args = { "-dNODISPLAY", "-sOutputFile=%stdout", "-f", "-" }; - gs.run(args); + public void testStdOut() throws Exception { + Path path = Paths.get("build/devicenames"); + try (OutputStream outputStream = Files.newOutputStream(path)) { + outputStream.write("devicenames ==\n".getBytes()); + } + try (Ghostscript gs = new Ghostscript()) { + List args = List.of("-dNODISPLAY", "-sOutputFile=%stdout", "-f", path.toString()); + int ret = gs.run(args); } catch (Exception e) { fail(e.getMessage()); + } finally { + Files.delete(path); } } @Test - public void testStdErr() { - try (Ghostscript gs = new Ghostscript(); - InputStream is = new ByteArrayInputStream("stupid\n".getBytes())) { - gs.setStdIn(is); - gs.setStdOut(new LoggingOutputStream(logger)); - gs.setStdErr(new LoggingOutputStream(logger)); - String[] args = { "-dNODISPLAY", "-sOutputFile=%stdout", "-f", "-" }; - gs.run(args); + public void testStdErr() throws Exception { + Path path = Paths.get("build/broken"); + try (OutputStream outputStream = Files.newOutputStream(path)) { + outputStream.write("foobar\n".getBytes()); + } + try (Ghostscript gs = new Ghostscript()) { + List args = List.of("-dNODISPLAY", "-sOutputFile=%stdout", "-f", path.toString()); + int ret = gs.run(args); } catch (Exception e) { // expect error if (!e.getMessage().contains("error code = -100")) { fail(e.getMessage()); } + } finally { + Files.delete(path); } } } diff --git a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostScriptLibraryTester.java b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostScriptLibraryTester.java index ec0138f..673f3ac 100644 --- a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostScriptLibraryTester.java +++ b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostScriptLibraryTester.java @@ -1,11 +1,15 @@ package org.xbib.graphics.ghostscript.test; 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.GhostscriptLibraryLoader; public class GhostScriptLibraryTester { + private static final Logger logger = Logger.getLogger(GhostScriptLibraryTester.class.getName()); + private final GhostscriptLibrary ghostscriptLibrary; public GhostScriptLibraryTester() { @@ -33,7 +37,7 @@ public class GhostScriptLibraryTester { GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); String[] args = { - "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" + "gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" }; ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); IntByReference exitCode = new IntByReference(); @@ -47,10 +51,8 @@ public class GhostScriptLibraryTester { GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); String[] args = { - "ps2pdf", - "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER", "-sDEVICE=pdfwrite", - "-sOutputFile=" + output, - "-c", ".setpdfwrite", "-f", input + "ps2pdf", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER", "-sDEVICE=pdfwrite", + "-sOutputFile=" + output, "-f", input }; int result = ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); 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.gsapi_new_instance(instanceByRef.getPointer(), null); String[] args = { - "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" + "gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" }; ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); IntByReference exitCode = new IntByReference(); @@ -77,7 +79,7 @@ public class GhostScriptLibraryTester { GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); String[] args = { - "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" + "gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" }; ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); IntByReference exitCode = new IntByReference(); @@ -94,7 +96,7 @@ public class GhostScriptLibraryTester { GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); String[] args = { - "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" + "gs", "-dNODISPLAY", "-dNOPAUSE", "-dBATCH", "-dSAFER" }; ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); IntByReference exitCode = new IntByReference(); @@ -108,9 +110,7 @@ public class GhostScriptLibraryTester { GhostscriptLibrary.gs_main_instance.ByReference instanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference(); ghostscriptLibrary.gsapi_new_instance(instanceByRef.getPointer(), null); final StringBuilder stdOutBuffer = new StringBuilder(); - final StringBuilder stdInBuffer = new StringBuilder(); GhostscriptLibrary.stdin_fn stdinCallback = (caller_handle, buf, len) -> { - stdInBuffer.append("OK"); return 0; }; 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.gsapi_set_stdio(instanceByRef.getValue(), stdinCallback, stdoutCallback, stderrCallback); String[] args = { - "-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", - "-sOutputFile=%stdout", "-f", "-" + "gs", "-dNODISPLAY", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-sOutputFile=%stdout", "-f", "-" }; ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), 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_exit(instanceByRef.getValue()); ghostscriptLibrary.gsapi_delete_instance(instanceByRef.getValue()); + logger.log(Level.FINE, stdOutBuffer.toString()); + } public String setDisplayCallback() { @@ -176,7 +177,7 @@ public class GhostScriptLibraryTester { displayCallback.size = displayCallback.size(); ghostscriptLibrary.gsapi_set_display_callback(instanceByRef.getValue(), displayCallback); String[] args = new String[]{ - "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER", + "gs", "-dQUIET", "-dNOPAUSE", "-dBATCH", "-dSAFER", "-sDEVICE=display", "-sDisplayHandle=0", "-dDisplayFormat=16#a0800" }; ghostscriptLibrary.gsapi_init_with_args(instanceByRef.getValue(), args.length, args); diff --git a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostscriptLibraryTest.java b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostscriptLibraryTest.java index cb0c06b..a45ab1f 100644 --- a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostscriptLibraryTest.java +++ b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/GhostscriptLibraryTest.java @@ -1,10 +1,9 @@ package org.xbib.graphics.ghostscript.test; +import java.util.logging.Level; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import java.io.File; import java.util.logging.Logger; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -19,9 +18,10 @@ public class GhostscriptLibraryTest { private static GhostScriptLibraryTester gslib; @BeforeAll - public static void setUp() throws Exception { + public static void setUp() { + logger.log(Level.INFO, "setUp: loading ghostscript library"); gslib = new GhostScriptLibraryTester(); - logger.info("setUp: ghostscript library loaded"); + logger.log(Level.INFO, "setUp: ghostscript library loaded"); } @Test @@ -35,13 +35,10 @@ public class GhostscriptLibraryTest { } @Test - @Disabled("GPL Ghostscript 9.54.0: Unrecoverable error, exit code 1") public void gsapiInitWithArgs() { String input = dir + "input.ps"; String output = "build/output.pdf"; gslib.withInput(input, output); - File outputFile = new File(output); - assertTrue(outputFile.exists()); } @Test @@ -70,9 +67,9 @@ public class GhostscriptLibraryTest { } @Test - @Disabled + //@Disabled public void gsapiSetDisplayCallback() { 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); } } diff --git a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/PDFConverterTest.java b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/PDFConverterTest.java index 72222a7..9e46691 100644 --- a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/PDFConverterTest.java +++ b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/PDFConverterTest.java @@ -20,7 +20,7 @@ public class PDFConverterTest { @Test 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"); ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { converter.convert(inputStream, outputStream); @@ -34,7 +34,7 @@ public class PDFConverterTest { final ByteArrayOutputStream baos1 = new ByteArrayOutputStream(); final ByteArrayOutputStream baos2 = 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() { public void run() { try { @@ -76,7 +76,6 @@ public class PDFConverterTest { baos3.close(); } - @Disabled @Test public void testConvertWithUnsupportedDocument() throws Exception { PDFConverter converter = new PDFConverter(); @@ -86,10 +85,9 @@ public class PDFConverterTest { } } - @Disabled @Test 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"); ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { converter.convert(inputStream, outputStream); diff --git a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/PDFRasterizerTest.java b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/PDFRasterizerTest.java index c3c8830..864cbfa 100644 --- a/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/PDFRasterizerTest.java +++ b/graphics-ghostscript/src/test/java/org/xbib/graphics/ghostscript/test/PDFRasterizerTest.java @@ -28,7 +28,7 @@ public class PDFRasterizerTest { Path targetFile = Paths.get("build/color.pdf"); PDFRasterizer pdfRasterizer = new PDFRasterizer(); int pagecount = pdfRasterizer.mergeImagesToPDF(sourceDir, targetFile); - logger.info("pagecount = " + pagecount); + logger.log(Level.FINE, "pagecount = " + pagecount); assertEquals(1, pagecount); } @@ -38,7 +38,7 @@ public class PDFRasterizerTest { Path targetFile = Paths.get("build/3656573.pdf"); PDFRasterizer pdfRasterizer = new PDFRasterizer(); int pagecount = pdfRasterizer.mergeImagesToPDF(sourceDir, targetFile); - logger.info("pagecount = " + pagecount); + logger.log(Level.FINE, "pagecount = " + pagecount); assertEquals(9, pagecount); } @@ -50,10 +50,10 @@ public class PDFRasterizerTest { int pagecount = 0; try { PDFRasterizer pdfRasterizer = new PDFRasterizer(); - pdfRasterizer.pdfToImage(source, path, null, null); + pdfRasterizer.pdfToImage(source, path, "test"); Path tmpTarget = path.resolve(target.getFileName()); pagecount = pdfRasterizer.mergeImagesToPDF(path, tmpTarget); - logger.info("pagecount = " + pagecount); + logger.log(Level.FINE, "pagecount = " + pagecount); pdfRasterizer.scalePDF(tmpTarget, target); } finally { delete(path); @@ -80,7 +80,7 @@ public class PDFRasterizerTest { delete(target); Files.createDirectories(target); PDFRasterizer rasterizer = new PDFRasterizer(); - rasterizer.pdfToImage(p, target, "pdf-", "1-"); + rasterizer.pdfToImage(p, target, "pdf-"); } catch (IOException e) { logger.log(Level.SEVERE, e.getMessage(), e); fail(e); @@ -96,7 +96,7 @@ public class PDFRasterizerTest { try (Stream stream = Files.list(path)) { stream.forEach(p -> { if (p.toString().endsWith(".pdf")) { - logger.info("found " + p.toString()); + logger.log(Level.FINE, "found " + p); Path target = Paths.get("build/" + p.getFileName()); try { delete(target);