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 group = org.xbib.graphics
name = graphics name = graphics
version = 4.3.2 version = 4.3.3
org.gradle.warning.mode = ALL org.gradle.warning.mode = ALL

View file

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

View file

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

View file

@ -106,9 +106,10 @@ public class PDFConverter {
if (outputStream == null) { if (outputStream == null) {
return; return;
} }
Ghostscript gs = Ghostscript.getInstance();
try {
prepare(tmpPath); prepare(tmpPath);
Path output = Files.createTempFile(tmpPath, "pdf", "pdf"); Path output = Files.createTempFile(tmpPath, "pdf", "pdf");
Ghostscript gs = Ghostscript.getInstance();
List<String> gsArgs = new LinkedList<>(); List<String> gsArgs = new LinkedList<>();
gsArgs.add("-ps2pdf"); gsArgs.add("-ps2pdf");
gsArgs.add("-dNOPAUSE"); gsArgs.add("-dNOPAUSE");
@ -174,6 +175,9 @@ public class PDFConverter {
} finally { } finally {
delete(tmpPath); delete(tmpPath);
} }
} finally {
gs.close();
}
} }
private static void prepare(Path path) throws IOException { private static void prepare(Path path) throws IOException {

View file

@ -143,11 +143,15 @@ public class PDFRasterizer {
logger.info("pdfToImage args=" + gsArgs); logger.info("pdfToImage args=" + gsArgs);
// reset stdin // reset stdin
Ghostscript gs = Ghostscript.getInstance(); Ghostscript gs = Ghostscript.getInstance();
try {
gs.setStdIn(null); gs.setStdIn(null);
gs.setStdOut(new LoggingOutputStream(logger)); gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger)); gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[gsArgs.size()])); gs.run(gsArgs.toArray(new String[gsArgs.size()]));
logger.info("pdfToImage done"); logger.info("pdfToImage done");
} finally {
gs.close();
}
} }
public synchronized void pdfToImage(Path sourceFile, public synchronized void pdfToImage(Path sourceFile,
@ -179,12 +183,16 @@ public class PDFRasterizer {
gsArgs.add(sourceFile.toString()); gsArgs.add(sourceFile.toString());
logger.info("pdfToImage args=" + gsArgs); logger.info("pdfToImage args=" + gsArgs);
Ghostscript gs = Ghostscript.getInstance(); Ghostscript gs = Ghostscript.getInstance();
try {
// reset stdin // reset stdin
gs.setStdIn(null); gs.setStdIn(null);
gs.setStdOut(new LoggingOutputStream(logger)); gs.setStdOut(new LoggingOutputStream(logger));
gs.setStdErr(new LoggingOutputStream(logger)); gs.setStdErr(new LoggingOutputStream(logger));
gs.run(gsArgs.toArray(new String[gsArgs.size()])); gs.run(gsArgs.toArray(new String[gsArgs.size()]));
logger.info("pdfToImage done"); logger.info("pdfToImage done");
} finally {
gs.close();
}
} }
public int mergeImagesToPDF(Path sourceDir, Path targetFile) throws IOException { public int mergeImagesToPDF(Path sourceDir, Path targetFile) throws IOException {
@ -287,10 +295,14 @@ public class PDFRasterizer {
gsArgs.add("-sOutputFile=" + targetFile.toString()); gsArgs.add("-sOutputFile=" + targetFile.toString());
gsArgs.add(sourceFile.toString()); gsArgs.add(sourceFile.toString());
Ghostscript gs = Ghostscript.getInstance(); Ghostscript gs = Ghostscript.getInstance();
try {
gs.setStdIn(null); gs.setStdIn(null);
logger.info(gsArgs.toString()); logger.info(gsArgs.toString());
gs.run(gsArgs.toArray(new String[gsArgs.size()])); gs.run(gsArgs.toArray(new String[gsArgs.size()]));
logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " done"); logger.info("scalePDF: source = " + sourceFile + " target = " + targetFile + " done");
} finally {
gs.close();
}
} }
public void toPDFA(Path source, Path target) throws IOException { public void toPDFA(Path source, Path target) throws IOException {
@ -326,14 +338,15 @@ 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());
try {
Ghostscript gs = Ghostscript.getInstance(); Ghostscript gs = Ghostscript.getInstance();
try {
gs.setStdIn(null); gs.setStdIn(null);
gs.run(gsArgs.toArray(new String[gsArgs.size()])); gs.run(gsArgs.toArray(new String[gsArgs.size()]));
} finally { } finally {
delete(pdfapsPathTmp); delete(pdfapsPathTmp);
delete(pdfapsPath); delete(pdfapsPath);
delete(iccPath); 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 com.sun.jna.ptr.IntByReference;
import org.xbib.graphics.ghostscript.internal.GhostscriptLibrary; 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.BeforeAll;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.graphics.ghostscript.GhostScriptLibraryTester;
import java.io.File; import java.io.File;
import java.util.logging.Logger; import java.util.logging.Logger;

View file

@ -1,5 +1,8 @@
package org.xbib.graphics.ghostscript.test; 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.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.graphics.ghostscript.Ghostscript; 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 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 @Test
public void testGetRevision() { public void testGetRevision() {