add close() method to Ghostscript

This commit is contained in:
Jörg Prante 2023-01-17 19:17:43 +01:00
parent 466cad318a
commit 3a79e6a87f
8 changed files with 166 additions and 114 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib.graphics
name = graphics
version = 4.3.2
version = 4.3.3
org.gradle.warning.mode = ALL

View file

@ -23,9 +23,9 @@ public class FontAnalyzer {
"-sFile=" + path.toAbsolutePath(),
"-sOutputFile=%stdout",
"-f", "-"};
Ghostscript gs = Ghostscript.getInstance();
try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("script/AnalyzePDFFonts.ps");
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
Ghostscript gs = Ghostscript.getInstance();
gs.setStdIn(is);
gs.setStdOut(baos);
gs.run(gsArgs);
@ -56,6 +56,8 @@ public class FontAnalyzer {
}
}
return result;
} finally {
gs.close();
}
}
}

View file

@ -31,32 +31,24 @@ public class Ghostscript {
private static Ghostscript INSTANCE;
private static InputStream stdIn;
private InputStream stdIn;
private static OutputStream stdOut;
private OutputStream stdOut;
private static OutputStream stdErr;
private OutputStream stdErr;
static {
try {
prepareTmp();
INSTANCE = new Ghostscript();
stdOut = new LoggingOutputStream(logger);
stdErr = new LoggingOutputStream(logger);
INSTANCE.setStdOut(stdOut);
INSTANCE.setStdErr(stdErr);
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
private GhostscriptLibrary libraryInstance;
private Ghostscript(GhostscriptLibrary libraryInstance) {
this.libraryInstance = libraryInstance;
this.stdOut = new LoggingOutputStream(logger);
this.stdErr = new LoggingOutputStream(logger);
}
public synchronized static Ghostscript getInstance() {
if (INSTANCE == null) {
INSTANCE = createInstance();
}
}
private final GhostscriptLibrary libraryInstance;
private Ghostscript() {
libraryInstance = GhostscriptLibraryLoader.loadLibrary();
}
public static Ghostscript getInstance() {
return INSTANCE;
}
@ -65,7 +57,7 @@ public class Ghostscript {
*
* @return the Ghostscript revision data.
*/
public static GhostscriptRevision getRevision() {
public synchronized static GhostscriptRevision getRevision() {
GhostscriptLibrary.gsapi_revision_s revision = new GhostscriptLibrary.gsapi_revision_s();
INSTANCE.libraryInstance.gsapi_revision(revision, revision.size());
GhostscriptRevision result = new GhostscriptRevision();
@ -83,7 +75,7 @@ public class Ghostscript {
*
* @return The OutputStream or null
*/
public synchronized OutputStream getStdErr() {
public OutputStream getStdErr() {
return stdErr;
}
@ -92,7 +84,7 @@ public class Ghostscript {
*
* @param outputStream OutputStream object
*/
public synchronized void setStdErr(OutputStream outputStream) {
public void setStdErr(OutputStream outputStream) {
stdErr = outputStream;
}
@ -101,7 +93,7 @@ public class Ghostscript {
*
* @return The OutputStream or null
*/
public synchronized OutputStream getStdOut() {
public OutputStream getStdOut() {
return stdOut;
}
@ -110,7 +102,7 @@ public class Ghostscript {
*
* @param outputStream OutputStream object
*/
public synchronized void setStdOut(OutputStream outputStream) {
public void setStdOut(OutputStream outputStream) {
stdOut = outputStream;
}
@ -119,7 +111,7 @@ public class Ghostscript {
*
* @return The InputStream or null
*/
public synchronized InputStream getStdIn() {
public InputStream getStdIn() {
return stdIn;
}
@ -128,7 +120,7 @@ public class Ghostscript {
*
* @param inputStream InputStream object
*/
public synchronized void setStdIn(InputStream inputStream) {
public void setStdIn(InputStream inputStream) {
stdIn = inputStream;
}
@ -265,6 +257,35 @@ public class Ghostscript {
}
}
public synchronized void close() throws IOException {
if (stdIn != null) {
stdIn.close();
stdIn = null;
}
if (stdOut != null) {
stdOut.close();
stdOut = null;
}
if (stdErr != null) {
stdErr.close();
stdErr = null;
}
libraryInstance = null;
INSTANCE = null;
System.gc();
logger.log(Level.INFO, "ghostscript instance closed and gc'ed()");
}
private static Ghostscript createInstance() {
try {
prepareTmp();
return new Ghostscript(GhostscriptLibraryLoader.loadLibrary());
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
return null;
}
private static void prepareTmp() throws IOException {
String tmp = System.getenv("TMPDIR"); // the variable that ghostscript uses
if (tmp == null) {

View file

@ -106,73 +106,77 @@ public class PDFConverter {
if (outputStream == null) {
return;
}
prepare(tmpPath);
Path output = Files.createTempFile(tmpPath, "pdf", "pdf");
Ghostscript gs = Ghostscript.getInstance();
List<String> gsArgs = new LinkedList<>();
gsArgs.add("-ps2pdf");
gsArgs.add("-dNOPAUSE");
//gsArgs.add("-dQUIET");
gsArgs.add("-dBATCH");
gsArgs.add("-dSAFER");
switch (autoRotatePages) {
case OPTION_AUTOROTATEPAGES_NONE:
gsArgs.add("-dAutoRotatePages=/None");
break;
case OPTION_AUTOROTATEPAGES_ALL:
gsArgs.add("-dAutoRotatePages=/All");
break;
case OPTION_AUTOROTATEPAGES_PAGEBYPAGE:
gsArgs.add("-dAutoRotatePages=/PageByPage");
break;
default:
break;
}
switch (processColorModel) {
case OPTION_PROCESSCOLORMODEL_CMYK:
gsArgs.add("-dProcessColorModel=/DeviceCMYK");
break;
case OPTION_PROCESSCOLORMODEL_GRAY:
gsArgs.add("-dProcessColorModel=/DeviceGray");
break;
default:
gsArgs.add("-dProcessColorModel=/DeviceRGB");
break;
}
switch (pdfsettings) {
case OPTION_PDFSETTINGS_EBOOK:
gsArgs.add("-dPDFSETTINGS=/ebook");
break;
case OPTION_PDFSETTINGS_SCREEN:
gsArgs.add("-dPDFSETTINGS=/screen");
break;
case OPTION_PDFSETTINGS_PRINTER:
gsArgs.add("-dPDFSETTINGS=/printer");
break;
case OPTION_PDFSETTINGS_PREPRESS:
gsArgs.add("-dPDFSETTINGS=/prepress");
break;
default:
gsArgs.add("-dPDFSETTINGS=/default");
break;
}
gsArgs.add("-dCompatibilityLevel=" + compatibilityLevel);
gsArgs.add("-dPDFX=" + pdfx);
gsArgs.add("-dDEVICEWIDTHPOINTS=" + paperSize.getWidth());
gsArgs.add("-dDEVICEHEIGHTPOINTS=" + paperSize.getHeight());
gsArgs.add("-sDEVICE=pdfwrite");
gsArgs.add("-sOutputFile=" + output.toAbsolutePath().toString());
//gsArgs.add("-q");
gsArgs.add("-f");
gsArgs.add("-");
try {
gs.setStdIn(inputStream);
gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[gsArgs.size()]));
Files.copy(output.toAbsolutePath(), outputStream);
prepare(tmpPath);
Path output = Files.createTempFile(tmpPath, "pdf", "pdf");
List<String> gsArgs = new LinkedList<>();
gsArgs.add("-ps2pdf");
gsArgs.add("-dNOPAUSE");
//gsArgs.add("-dQUIET");
gsArgs.add("-dBATCH");
gsArgs.add("-dSAFER");
switch (autoRotatePages) {
case OPTION_AUTOROTATEPAGES_NONE:
gsArgs.add("-dAutoRotatePages=/None");
break;
case OPTION_AUTOROTATEPAGES_ALL:
gsArgs.add("-dAutoRotatePages=/All");
break;
case OPTION_AUTOROTATEPAGES_PAGEBYPAGE:
gsArgs.add("-dAutoRotatePages=/PageByPage");
break;
default:
break;
}
switch (processColorModel) {
case OPTION_PROCESSCOLORMODEL_CMYK:
gsArgs.add("-dProcessColorModel=/DeviceCMYK");
break;
case OPTION_PROCESSCOLORMODEL_GRAY:
gsArgs.add("-dProcessColorModel=/DeviceGray");
break;
default:
gsArgs.add("-dProcessColorModel=/DeviceRGB");
break;
}
switch (pdfsettings) {
case OPTION_PDFSETTINGS_EBOOK:
gsArgs.add("-dPDFSETTINGS=/ebook");
break;
case OPTION_PDFSETTINGS_SCREEN:
gsArgs.add("-dPDFSETTINGS=/screen");
break;
case OPTION_PDFSETTINGS_PRINTER:
gsArgs.add("-dPDFSETTINGS=/printer");
break;
case OPTION_PDFSETTINGS_PREPRESS:
gsArgs.add("-dPDFSETTINGS=/prepress");
break;
default:
gsArgs.add("-dPDFSETTINGS=/default");
break;
}
gsArgs.add("-dCompatibilityLevel=" + compatibilityLevel);
gsArgs.add("-dPDFX=" + pdfx);
gsArgs.add("-dDEVICEWIDTHPOINTS=" + paperSize.getWidth());
gsArgs.add("-dDEVICEHEIGHTPOINTS=" + paperSize.getHeight());
gsArgs.add("-sDEVICE=pdfwrite");
gsArgs.add("-sOutputFile=" + output.toAbsolutePath().toString());
//gsArgs.add("-q");
gsArgs.add("-f");
gsArgs.add("-");
try {
gs.setStdIn(inputStream);
gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[gsArgs.size()]));
Files.copy(output.toAbsolutePath(), outputStream);
} finally {
delete(tmpPath);
}
} finally {
delete(tmpPath);
gs.close();
}
}

View file

@ -143,11 +143,15 @@ public class PDFRasterizer {
logger.info("pdfToImage args=" + gsArgs);
// reset stdin
Ghostscript gs = Ghostscript.getInstance();
gs.setStdIn(null);
gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[gsArgs.size()]));
logger.info("pdfToImage done");
try {
gs.setStdIn(null);
gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[gsArgs.size()]));
logger.info("pdfToImage done");
} finally {
gs.close();
}
}
public synchronized void pdfToImage(Path sourceFile,
@ -179,12 +183,16 @@ public class PDFRasterizer {
gsArgs.add(sourceFile.toString());
logger.info("pdfToImage args=" + gsArgs);
Ghostscript gs = Ghostscript.getInstance();
// reset stdin
gs.setStdIn(null);
gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[gsArgs.size()]));
logger.info("pdfToImage done");
try {
// reset stdin
gs.setStdIn(null);
gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[gsArgs.size()]));
logger.info("pdfToImage done");
} finally {
gs.close();
}
}
public int mergeImagesToPDF(Path sourceDir, Path targetFile) throws IOException {
@ -287,10 +295,14 @@ public class PDFRasterizer {
gsArgs.add("-sOutputFile=" + targetFile.toString());
gsArgs.add(sourceFile.toString());
Ghostscript gs = Ghostscript.getInstance();
gs.setStdIn(null);
logger.info(gsArgs.toString());
gs.run(gsArgs.toArray(new String[gsArgs.size()]));
logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " done");
try {
gs.setStdIn(null);
logger.info(gsArgs.toString());
gs.run(gsArgs.toArray(new String[gsArgs.size()]));
logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " done");
} finally {
gs.close();
}
}
public void toPDFA(Path source, Path target) throws IOException {
@ -326,14 +338,15 @@ public class PDFRasterizer {
gsArgs.add("-sOutputFile=" + target.toString());
gsArgs.add(pdfapsPath.toAbsolutePath().toString());
gsArgs.add(source.toString());
Ghostscript gs = Ghostscript.getInstance();
try {
Ghostscript gs = Ghostscript.getInstance();
gs.setStdIn(null);
gs.run(gsArgs.toArray(new String[gsArgs.size()]));
} finally {
delete(pdfapsPathTmp);
delete(pdfapsPath);
delete(iccPath);
gs.close();
}
}

View file

@ -1,4 +1,4 @@
package org.xbib.graphics.ghostscript;
package org.xbib.graphics.ghostscript.test;
import com.sun.jna.ptr.IntByReference;
import org.xbib.graphics.ghostscript.internal.GhostscriptLibrary;

View file

@ -3,7 +3,6 @@ package org.xbib.graphics.ghostscript.test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.ghostscript.GhostScriptLibraryTester;
import java.io.File;
import java.util.logging.Logger;

View file

@ -1,5 +1,8 @@
package org.xbib.graphics.ghostscript.test;
import java.io.IOException;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.ghostscript.Ghostscript;
@ -20,7 +23,17 @@ public class GhostscriptTest {
private static final String dir = "src/test/resources/org/xbib/graphics/ghostscript/test/";
private static final Ghostscript gs = Ghostscript.getInstance();
static Ghostscript gs;
@BeforeAll
public static void init() {
gs = Ghostscript.getInstance();
}
@AfterAll
public static void shutdown() throws IOException {
gs.close();
}
@Test
public void testGetRevision() {