mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-02-17 13:52:14 +01:00
feat: custom error handling when calling renderImageWithDPI, controllers to respect global DPI (#4407)
This commit is contained in:
@@ -34,7 +34,10 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest;
|
||||
import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.common.util.ApplicationContextProvider;
|
||||
import stirling.software.common.util.ExceptionUtils;
|
||||
import stirling.software.common.util.TempFile;
|
||||
import stirling.software.common.util.TempFileManager;
|
||||
import stirling.software.common.util.WebResponseUtils;
|
||||
@@ -128,7 +131,23 @@ public class AutoSplitPdfController {
|
||||
pdfRenderer.setSubsamplingAllowed(true);
|
||||
|
||||
for (int page = 0; page < document.getNumberOfPages(); ++page) {
|
||||
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
|
||||
BufferedImage bim;
|
||||
|
||||
// Use global maximum DPI setting, fallback to 300 if not set
|
||||
int renderDpi = 150; // Default fallback
|
||||
ApplicationProperties properties =
|
||||
ApplicationContextProvider.getBean(ApplicationProperties.class);
|
||||
if (properties != null && properties.getSystem() != null) {
|
||||
renderDpi = properties.getSystem().getMaxDPI();
|
||||
}
|
||||
|
||||
try {
|
||||
bim = pdfRenderer.renderImageWithDPI(page, renderDpi);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(page + 1, renderDpi, e);
|
||||
} catch (NegativeArraySizeException e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(page + 1, renderDpi, e);
|
||||
}
|
||||
String result = decodeQRCode(bim);
|
||||
|
||||
boolean isValidQrCode = VALID_QR_CONTENTS.contains(result);
|
||||
|
||||
@@ -30,7 +30,10 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.api.misc.RemoveBlankPagesRequest;
|
||||
import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.common.util.ApplicationContextProvider;
|
||||
import stirling.software.common.util.ExceptionUtils;
|
||||
import stirling.software.common.util.PdfUtils;
|
||||
import stirling.software.common.util.WebResponseUtils;
|
||||
|
||||
@@ -108,7 +111,25 @@ public class BlankPageController {
|
||||
if (hasImages) {
|
||||
log.info("page {} has image, running blank detection", pageIndex);
|
||||
// Render image and save as temp file
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 30);
|
||||
BufferedImage image;
|
||||
|
||||
// Use global maximum DPI setting
|
||||
int renderDpi = 30; // Default fallback
|
||||
ApplicationProperties properties =
|
||||
ApplicationContextProvider.getBean(ApplicationProperties.class);
|
||||
if (properties != null && properties.getSystem() != null) {
|
||||
renderDpi = properties.getSystem().getMaxDPI();
|
||||
}
|
||||
|
||||
try {
|
||||
image = pdfRenderer.renderImageWithDPI(pageIndex, renderDpi);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(
|
||||
pageIndex + 1, renderDpi, e);
|
||||
} catch (NegativeArraySizeException e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(
|
||||
pageIndex + 1, renderDpi, e);
|
||||
}
|
||||
blank = isBlankImage(image, threshold, whitePercent, threshold);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,9 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.api.misc.ExtractImageScansRequest;
|
||||
import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.common.util.ApplicationContextProvider;
|
||||
import stirling.software.common.util.CheckProgramInstall;
|
||||
import stirling.software.common.util.ExceptionUtils;
|
||||
import stirling.software.common.util.GeneralUtils;
|
||||
@@ -97,7 +99,23 @@ public class ExtractImageScansController {
|
||||
Path tempFile = Files.createTempFile("image_", ".png");
|
||||
|
||||
// Render image and save as temp file
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(i, 300);
|
||||
BufferedImage image;
|
||||
|
||||
// Use global maximum DPI setting, fallback to 300 if not set
|
||||
int renderDpi = 300; // Default fallback
|
||||
ApplicationProperties properties =
|
||||
ApplicationContextProvider.getBean(ApplicationProperties.class);
|
||||
if (properties != null && properties.getSystem() != null) {
|
||||
renderDpi = properties.getSystem().getMaxDPI();
|
||||
}
|
||||
|
||||
try {
|
||||
image = pdfRenderer.renderImageWithDPI(i, renderDpi);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(i + 1, renderDpi, e);
|
||||
} catch (NegativeArraySizeException e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(i + 1, renderDpi, e);
|
||||
}
|
||||
ImageIO.write(image, "png", tempFile.toFile());
|
||||
|
||||
// Add temp file path to images list
|
||||
|
||||
@@ -27,7 +27,10 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.api.misc.FlattenRequest;
|
||||
import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.common.util.ApplicationContextProvider;
|
||||
import stirling.software.common.util.ExceptionUtils;
|
||||
import stirling.software.common.util.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
@@ -67,7 +70,23 @@ public class FlattenController {
|
||||
int numPages = document.getNumberOfPages();
|
||||
for (int i = 0; i < numPages; i++) {
|
||||
try {
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(i, 300, ImageType.RGB);
|
||||
BufferedImage image;
|
||||
|
||||
// Use global maximum DPI setting, fallback to 300 if not set
|
||||
int renderDpi = 300; // Default fallback
|
||||
ApplicationProperties properties =
|
||||
ApplicationContextProvider.getBean(ApplicationProperties.class);
|
||||
if (properties != null && properties.getSystem() != null) {
|
||||
renderDpi = properties.getSystem().getMaxDPI();
|
||||
}
|
||||
|
||||
try {
|
||||
image = pdfRenderer.renderImageWithDPI(i, renderDpi, ImageType.RGB);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(i + 1, renderDpi, e);
|
||||
} catch (NegativeArraySizeException e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(i + 1, renderDpi, e);
|
||||
}
|
||||
PDPage page = new PDPage();
|
||||
page.setMediaBox(document.getPage(i).getMediaBox());
|
||||
newDocument.addPage(page);
|
||||
|
||||
@@ -359,7 +359,24 @@ public class OCRController {
|
||||
|
||||
if (shouldOcr) {
|
||||
// Convert page to image
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(pageNum, 300);
|
||||
BufferedImage image;
|
||||
|
||||
// Use global maximum DPI setting, fallback to 300 if not set
|
||||
int renderDpi = 300; // Default fallback
|
||||
if (applicationProperties != null
|
||||
&& applicationProperties.getSystem() != null) {
|
||||
renderDpi = applicationProperties.getSystem().getMaxDPI();
|
||||
}
|
||||
|
||||
try {
|
||||
image = pdfRenderer.renderImageWithDPI(pageNum, renderDpi);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(
|
||||
pageNum + 1, renderDpi, e);
|
||||
} catch (NegativeArraySizeException e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(
|
||||
pageNum + 1, renderDpi, e);
|
||||
}
|
||||
File imagePath =
|
||||
new File(tempImagesDir, String.format("page_%d.png", pageNum));
|
||||
ImageIO.write(image, "png", imagePath);
|
||||
|
||||
@@ -34,7 +34,10 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.api.misc.ScannerEffectRequest;
|
||||
import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.common.util.ApplicationContextProvider;
|
||||
import stirling.software.common.util.ExceptionUtils;
|
||||
import stirling.software.common.util.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
@@ -82,6 +85,22 @@ public class ScannerEffectController {
|
||||
int resolution = request.getResolution();
|
||||
ScannerEffectRequest.Colorspace colorspace = request.getColorspace();
|
||||
|
||||
// Validate and limit DPI to prevent excessive memory usage (respecting global limits)
|
||||
int maxSafeDpi = 500; // Default maximum safe DPI
|
||||
ApplicationProperties properties =
|
||||
ApplicationContextProvider.getBean(ApplicationProperties.class);
|
||||
if (properties != null && properties.getSystem() != null) {
|
||||
maxSafeDpi = properties.getSystem().getMaxDPI();
|
||||
}
|
||||
if (resolution > maxSafeDpi) {
|
||||
throw ExceptionUtils.createIllegalArgumentException(
|
||||
"error.dpiExceedsLimit",
|
||||
"DPI value {0} exceeds maximum safe limit of {1}. High DPI values can cause"
|
||||
+ " memory issues and crashes. Please use a lower DPI value.",
|
||||
resolution,
|
||||
maxSafeDpi);
|
||||
}
|
||||
|
||||
try (PDDocument document = pdfDocumentFactory.load(file)) {
|
||||
PDDocument outputDocument = new PDDocument();
|
||||
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||
@@ -118,7 +137,14 @@ public class ScannerEffectController {
|
||||
}
|
||||
|
||||
// Render page to image with safe resolution
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(i, safeResolution);
|
||||
BufferedImage image;
|
||||
try {
|
||||
image = pdfRenderer.renderImageWithDPI(i, safeResolution);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(i + 1, safeResolution, e);
|
||||
} catch (NegativeArraySizeException e) {
|
||||
throw ExceptionUtils.createOutOfMemoryDpiException(i + 1, safeResolution, e);
|
||||
}
|
||||
|
||||
log.debug(
|
||||
"Processing page {} with dimensions {}x{} ({} pixels) at {}dpi",
|
||||
|
||||
Reference in New Issue
Block a user