summaryrefslogtreecommitdiff
path: root/pdf-over-signer/src/main/java/at/asit/pdfover/signer/Emblem.java
diff options
context:
space:
mode:
Diffstat (limited to 'pdf-over-signer/src/main/java/at/asit/pdfover/signer/Emblem.java')
-rw-r--r--pdf-over-signer/src/main/java/at/asit/pdfover/signer/Emblem.java200
1 files changed, 200 insertions, 0 deletions
diff --git a/pdf-over-signer/src/main/java/at/asit/pdfover/signer/Emblem.java b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/Emblem.java
new file mode 100644
index 00000000..c045169a
--- /dev/null
+++ b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/Emblem.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package at.asit.pdfover.signer;
+
+// Imports
+import at.asit.pdfover.commons.Constants;
+import at.asit.pdfover.commons.utils.ImageUtil;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Properties;
+
+import javax.imageio.ImageIO;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TODO all of this caching business is a bit of a mess
+ */
+public class Emblem {
+ /**
+ * SLF4J Logger instance
+ **/
+ private static final Logger log = LoggerFactory.getLogger(Emblem.class);
+
+ private static final String CACHE_DIR = Constants.CONFIG_DIRECTORY;
+ private static final String CACHE_IMG_FILENAME = ".emblem.png";
+ private static final String CACHE_IMG_FORMAT = "png";
+ private static final String CACHE_PROPS_FILENAME = ".emblem.properties";
+
+ private static final String PROPKEY_ORIG_PATH = "IMG";
+ private static final String PROPKEY_ORIG_DIGEST = "HSH";
+ private static final int MAX_EMBLEM_WIDTH = 480;
+ private static final int MAX_EMBLEM_HEIGHT = 600;
+
+ private String originalFileName = null;
+ private String originalFileHash = null;
+ private Image image = null; /* image data, if we have it */
+
+ private void lazyLoadImage() {
+ if (this.image != null) return;
+
+ String filename = getCachedFileName();
+ if (this.image != null) return; /* getCachedFileName may have re-generated the cache and populated this.image */
+
+ try {
+ this.image = ImageUtil.readImageWithEXIFRotation(new File(filename));
+ } catch (IOException e) {
+ log.warn("Failed to load Emblem image");
+ }
+ }
+
+ public int getWidth() { if (image == null) lazyLoadImage(); return (image != null) ? image.getWidth(null) : 0; }
+ public int getHeight() { if (image == null) lazyLoadImage(); return (image != null) ? image.getHeight(null) : 0; }
+
+ /**
+ * Constructor
+ * @param filename
+ */
+ public Emblem(String filename) {
+ this.originalFileName = filename;
+ }
+
+ private String getFileHash(String filename) throws IOException {
+ InputStream is = Files.newInputStream(Path.of(filename));
+ return DigestUtils.md5Hex(is);
+ }
+
+ private static BufferedImage reduceImageSizeIfNecessary(BufferedImage img, int maxWidth, int maxHeight) {
+ int oheight = img.getHeight();
+ int owidth = img.getWidth();
+
+ double ratio = (double)owidth/(double)oheight;
+
+ int height = oheight;
+ int width = owidth;
+ if (height > maxHeight) {
+ height = maxHeight;
+ width = (int) (maxHeight * ratio);
+ }
+ if (width > maxWidth) {
+ width = maxWidth;
+ height = (int) (maxWidth / ratio);
+ }
+ BufferedImage result = img;
+ if (width != owidth || height != oheight) {
+ //scale image
+ log.debug("Scaling emblem: " + owidth + "x" + oheight + " to " + width + "x" + height);
+ result = new BufferedImage(width, height, img.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : img.getType());
+ Graphics2D g = result.createGraphics();
+ g.drawImage(img, 0, 0, width, height, null);
+ g.dispose();
+ }
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see at.asit.pdfover.signator.Emblem#getFileName()
+ */
+ public String getCachedFileName() {
+ String emblemImg = this.originalFileName;
+ String emblemHsh = null;
+ String cachedEmblemFileName = CACHE_DIR + File.separator + CACHE_IMG_FILENAME;
+
+ if (emblemImg == null || !(new File(emblemImg).exists()))
+ return null;
+
+ Properties emblemProps = new Properties();
+ // compare cache, try to load if match
+ try {
+ File cacheProps = new File(CACHE_DIR, CACHE_PROPS_FILENAME);
+ if (cacheProps.exists()) {
+ InputStream in = new FileInputStream(cacheProps);
+ emblemProps.load(in);
+ if (emblemImg.equals(emblemProps.getProperty(PROPKEY_ORIG_PATH))) {
+ emblemHsh = getFileHash(emblemImg);
+ if (emblemHsh.equals(emblemProps.getProperty(PROPKEY_ORIG_DIGEST))) {
+ log.debug("Emblem cache hit: " + cachedEmblemFileName);
+ return cachedEmblemFileName;
+ }
+ }
+ }
+ log.debug("Emblem cache miss");
+ } catch (Exception e) {
+ log.warn("Can't load emblem cache", e);
+ }
+
+ try {
+ // create new cache
+ if (emblemHsh == null)
+ emblemHsh = getFileHash(emblemImg);
+ emblemProps.setProperty(PROPKEY_ORIG_PATH, emblemImg);
+ emblemProps.setProperty(PROPKEY_ORIG_DIGEST, emblemHsh);
+ File imgFile = new File(emblemImg);
+
+ BufferedImage img = ImageUtil.readImageWithEXIFRotation(imgFile);
+ img = reduceImageSizeIfNecessary(img, MAX_EMBLEM_WIDTH, MAX_EMBLEM_HEIGHT);
+
+ File file = new File(CACHE_DIR, CACHE_IMG_FILENAME);
+ ImageIO.write(img, CACHE_IMG_FORMAT, file); // ignore returned boolean
+ this.image = img;
+ OutputStream out = new FileOutputStream(new File(CACHE_DIR, CACHE_PROPS_FILENAME));
+ emblemProps.store(out, null);
+ } catch (IOException e) {
+ log.error("Can't save emblem cache", e);
+ return this.originalFileName;
+ }
+ return cachedEmblemFileName;
+ }
+
+ /**
+ * Return the original filename
+ * @return the original filename
+ */
+ public String getOriginalFileName() {
+ return this.originalFileName;
+ }
+
+ /**
+ * Return the original filename
+ * @return the original filename
+ */
+ public String getOriginalFileHash() {
+ if (this.originalFileHash == null) {
+ if (this.originalFileName == null || !(new File(this.originalFileName).exists())) {
+ this.originalFileHash = "";
+ } else try {
+ this.originalFileHash = getFileHash(this.originalFileName);
+ } catch (IOException e) {
+ log.debug("Error getting file hash", e);
+ this.originalFileHash = "";
+ }
+ }
+ return this.originalFileHash;
+ }
+}