From 27c704951d9b440dc9c7a2dedafe854de520650d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Sz=C3=BCcs?= Date: Sat, 15 Nov 2025 18:17:06 +0100 Subject: [PATCH] feat(compress): add PDF linearization option using QPDF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Balázs Szücs --- .../api/misc/CompressController.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java index 865a95c5c..1fecc1aef 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java @@ -791,6 +791,16 @@ public class CompressController { currentFile = originalFile; } + // Apply linearization as final step if requested + if (Boolean.TRUE.equals(request.getLinearize()) && isQpdfEnabled()) { + try { + applyLinearization(currentFile, tempFiles); + log.info("PDF linearization applied successfully"); + } catch (IOException e) { + log.warn("PDF linearization failed, continuing without linearization", e); + } + } + String outputFilename = GeneralUtils.generateFilename( inputFile.getOriginalFilename(), "_Optimized.pdf"); @@ -810,6 +820,36 @@ public class CompressController { } } + // Apply PDF linearization using QPDF + private void applyLinearization(Path currentFile, List tempFiles) throws IOException { + log.info("Applying PDF linearization to: {}", currentFile); + + // Create output file for linearization + Path linearizedOutputFile = Files.createTempFile("linearized_output_", ".pdf"); + tempFiles.add(linearizedOutputFile); + + // Build QPDF command for linearization only + List command = new ArrayList<>(); + command.add("qpdf"); + command.add("--linearize"); + command.add(currentFile.toString()); + command.add(linearizedOutputFile.toString()); + + try { + ProcessExecutorResult returnCode = + ProcessExecutor.getInstance(ProcessExecutor.Processes.QPDF) + .runCommandWithOutputHandling(command); + + // Update current file to the linearized output + Files.copy(linearizedOutputFile, currentFile, StandardCopyOption.REPLACE_EXISTING); + + log.info("PDF linearization completed successfully"); + } catch (Exception e) { + log.warn("PDF linearization failed", e); + throw new IOException("PDF linearization failed", e); + } + } + // Run Ghostscript compression private void applyGhostscriptCompression( OptimizePdfRequest request, int optimizeLevel, Path currentFile, List tempFiles)