From f39ab43fc0120b7fa97028d40acd7851de8d4a99 Mon Sep 17 00:00:00 2001 From: Jakob Heher Date: Thu, 24 Nov 2022 14:14:37 +0100 Subject: Repository moved to GitHub: https://github.com/a-sit/pdf-over --- .../main/java/at/asit/pdfover/commons/BKUs.java | 34 -- .../java/at/asit/pdfover/commons/Constants.java | 390 --------------------- .../java/at/asit/pdfover/commons/Messages.java | 127 ------- .../main/java/at/asit/pdfover/commons/Profile.java | 53 --- .../at/asit/pdfover/commons/utils/ImageUtil.java | 290 --------------- 5 files changed, 894 deletions(-) delete mode 100644 pdf-over-commons/src/main/java/at/asit/pdfover/commons/BKUs.java delete mode 100644 pdf-over-commons/src/main/java/at/asit/pdfover/commons/Constants.java delete mode 100644 pdf-over-commons/src/main/java/at/asit/pdfover/commons/Messages.java delete mode 100644 pdf-over-commons/src/main/java/at/asit/pdfover/commons/Profile.java delete mode 100644 pdf-over-commons/src/main/java/at/asit/pdfover/commons/utils/ImageUtil.java (limited to 'pdf-over-commons/src/main/java/at/asit/pdfover') diff --git a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/BKUs.java b/pdf-over-commons/src/main/java/at/asit/pdfover/commons/BKUs.java deleted file mode 100644 index bcba609e..00000000 --- a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/BKUs.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.commons; - -/** - * Enumeration of available BKU types - * - */ -public enum BKUs { - /** Local BKU */ - LOCAL, - - /** Mobile BKU */ - MOBILE, - - /** KeyStore */ - KS, - - /** No BKU */ - NONE -} diff --git a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/Constants.java b/pdf-over-commons/src/main/java/at/asit/pdfover/commons/Constants.java deleted file mode 100644 index 1d482fcf..00000000 --- a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/Constants.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * 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.commons; - -import java.io.File; -import java.io.FileInputStream; -import java.net.URI; -import java.util.Locale; -import java.util.Properties; - -import javax.annotation.Nonnull; - -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Display; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * Various constants - */ -public class Constants { - - static private final Logger log = LoggerFactory.getLogger(Constants.class); - - /** Application name */ - public static final String APP_NAME = "PDF-Over"; - - /** Application version */ - public static final String APP_VERSION; - static - { - String v = null; - try { - Properties props = new Properties(); - props.load(Constants.class.getClassLoader().getResourceAsStream("version.properties")); - v = props.getProperty("version"); - } catch (Exception e) { - log.warn("Failed to load project version", e); - v = "UNKNOWN-SNAPSHOT"; - } - APP_VERSION = v; - } - - /** Application name + version */ - public static final String APP_NAME_VERSION = (APP_NAME + " v" + APP_VERSION); - - public static final String SIGNATURE_PROFILE = "SIGNATURE_PROFILE"; - public static final String DEFAULT_POSTFIX = "_signed"; - - static { - // Has to be set before (implicitly) initializing Display - Display.setAppName(APP_NAME); - } - - /** - * - */ - public static final String SIGNATURE_FIELD_NAME_CONF = "signature_field_name"; - - /** Current display - used for Colors */ - private static Display display = Display.getCurrent(); - - /** Supported locales */ - public static final Locale[] SUPPORTED_LOCALES = { Locale.GERMAN, Locale.ENGLISH }; - - /** Configuration directory */ - public static final String CONFIG_DIRECTORY = System.getProperty("user.home") + File.separator + ".pdf-over"; - - /** Directory for config backup on factory reset */ - public static final String CONFIG_BACKUP_DIRECTORY = System.getProperty("user.home") + File.separator + ".pdf-over.old"; - - /** The default configuration file name */ - public static final String DEFAULT_CONFIG_FILENAME = "PDF-Over.config"; - - /** The configuration version file name */ - public static final String CONFIG_VERSION_FILENAME = ".version"; - - /** - * The minimum PDF-AS configuration version (older ones will be backed up - * and updated - */ - public static final String MIN_PDF_AS_CONFIG_VERSION = "4.2.1-snapshot"; - - /** The configuration backup filename */ - public static final String PDF_AS_CONFIG_BACKUP_FILENAME = "cfg_backup"; - - /** File suffix for the signed document */ - public final static String SIGNED_SUFFIX = "_signed"; - - public final static double PDF_UNITS_PER_MM = (595.0 / 210.0); - - /** The default target size for logo-only signatures (in mm) */ - public final static double DEFAULT_LOGO_ONLY_SIZE = 23; - - /** Local BKU URL */ - public static final String LOCAL_BKU_URL = "http://127.0.0.1:3495/http-security-layer-request"; - - /** Default Mobile BKU URL */ - public static final URI MOBILE_BKU_URL = URI.create("https://www.a-trust.at/mobile/https-security-layer-request/default.aspx"); - - /** How far to displace the signature with the arrow keys */ - public static final int SIGNATURE_KEYBOARD_POSITIONING_OFFSET = 15; - - /** Current release file */ - public static final String CURRENT_RELEASE_URL = "https://updates.a-sit.at/pdf-over/Release.txt"; - - /** Update URL */ - public static final String UPDATE_URL = "https://technology.a-sit.at/en/pdf-over/"; - - /** True */ - public static final String TRUE = "true"; - - /** False */ - public static final String FALSE = "false"; - - /* Configuration parameters */ - - /** The bku config parameter */ - public static final String CFG_BKU = "BKU"; - - /** - * The value for the Signature position in the configuration file values for - * this entry are: - * - * x=vx;y=vy;p=vp or auto - * - * vx:= float value vy:= float value vp:= integer value - */ - public static final String CFG_SIGNATURE_POSITION = "SIGNATURE_POSITION"; - - /** The use marker parameter (true/false) */ - public static final String CFG_USE_MARKER = "USE_MARKER"; - - /** The use of signature fields instead of QR codes */ - public static final String CFG_USE_SIGNATURE_FIELDS = "USE_FIELDS"; - - /** */ - public static final String CFG_ENABLE_PLACEHOLDER = "USE_PLACEHOLDER_SEARCH"; - - /** The signature placeholder transparency config parameter (0-255) */ - public static final String CFG_SIGNATURE_PLACEHOLDER_TRANSPARENCY = "SIGNATURE_PLACEHOLDER_TRANSPARENCY"; - - /** The mobile number config parameter */ - public static final String CFG_MOBILE_NUMBER = "MOBILE_NUMBER"; - public static final String CFG_MOBILE_PASSWORD_REMEMBER = "MOBILE_REMEMBER_PASSWORD"; - - /** The signature note config parameter */ - public static final String CFG_SIGNATURE_NOTE = "SIGNATURE_NOTE"; - - /** The signature locale config parameter */ - public static final String CFG_SIGNATURE_LOCALE = "SIGNLOCALE"; - - /** The PDF/A-compatibility config parameter */ - public static final String CFG_SIGNATURE_PDFA_COMPAT = "SIGNATURE_PDFA_COMPAT"; - - /** KeyStore enabled config parameter */ - public static final String CFG_KEYSTORE_ENABLED = "KEYSTORE_ENABLED"; - - /** KeyStore file config parameter */ - public static final String CFG_KEYSTORE_FILE = "KEYSTORE_FILE"; - - /** KeyStore type config parameter */ - public static final String CFG_KEYSTORE_TYPE = "KEYSTORE_TYPE"; - - /** KeyStore alias config parameter */ - public static final String CFG_KEYSTORE_ALIAS = "KEYSTORE_ALIAS"; - - public static final String CFG_KEYSTORE_PASSSTORETYPE = "KEYSTORE_PASS_STORE_TYPE"; - - /** KeyStore store password config parameter */ - public static final String CFG_KEYSTORE_STOREPASS = "KEYSTORE_STOREPASS"; - - /** KeyStore key password config parameter */ - public static final String CFG_KEYSTORE_KEYPASS = "KEYSTORE_KEYPASS"; - - /** The emblem config parameter */ - public static final String CFG_EMBLEM = "EMBLEM"; - - /** The emblem size config parameter */ - public static final String CFG_LOGO_ONLY_SIZE = "LOGO_ONLY_SIZE"; - - /** The locale config parameter */ - public static final String CFG_LOCALE = "LOCALE"; - - /** The update check config parameter */ - public static final String CFG_UPDATE_CHECK = "UPDATE_CHECK"; - - /** The proxy host config parameter */ - public static final String CFG_PROXY_HOST = "PROXY_HOST"; - - /** The proxy port config parameter */ - public static final String CFG_PROXY_PORT = "PROXY_PORT"; - - /** The proxy username config parameter */ - public static final String CFG_PROXY_USER = "PROXY_USER"; - - /** The proxy password config parameter */ - public static final String CFG_PROXY_PASS = "PROXY_PASS"; - - /** The output folder config parameter */ - public static final String CFG_OUTPUT_FOLDER = "OUTPUT_FOLDER"; - - public static final String CFG_POSTFIX = "SAVE_FILE_POSTFIX"; - - /** The main window size (Format: width,height) */ - public static final String CFG_MAINWINDOW_SIZE = "MAINWINDOW_SIZE"; - - /** The theme */ - public static final String CFG_THEME = "THEME"; - - public static final String CFG_FIDO2_BY_DEFAULT = "FIDO2_DEFAULT"; - - /** Download URL for accepted Certificates*/ - public static final String CFG_DOWNLOAD_URL="DOWNLOAD_URL"; - - /* Theme constants */ - - /** The available themes */ - public static enum Themes { - /** Default theme */ DEFAULT, - /** GemPlush theme */ GEMPLUSH - }; - - /** The used theme */ - public static final Themes THEME = getTheme(); - - private static Themes getTheme() { - File f = new File(CONFIG_DIRECTORY + File.separatorChar + DEFAULT_CONFIG_FILENAME); - if (f.canRead()) { - try { - Properties config = new Properties(); - config.load(new FileInputStream(f)); - return Themes.valueOf(config.getProperty(CFG_THEME).toUpperCase()); - } catch (Exception e) { - // Ignore - } - } - return Themes.DEFAULT; - } - - /** Main window height */ - public static final int DEFAULT_MAINWINDOW_HEIGHT = 780; - - /** Main window width */ - public static final int DEFAULT_MAINWINDOW_WIDTH = 600; - - /** Main bar height */ - public static final int MAINBAR_HEIGHT = 60; - - /** Main bar active background - light start of gradient */ - public static final Color MAINBAR_ACTIVE_BACK_LIGHT = getMainbarActiveBackLight(); - private static Color getMainbarActiveBackLight() { - switch (THEME) { - default: - case DEFAULT: - return new Color(display, 0xB4, 0xCD, 0xEC); - case GEMPLUSH: - return new Color(display, 0xEC, 0xAD, 0xE7); - } - } - - /** Main bar active background - dark end of gradient */ - public static final Color MAINBAR_ACTIVE_BACK_DARK = getMainbarActiveBackDark(); - - private static Color getMainbarActiveBackDark() { - switch (THEME) { - default: - case DEFAULT: - return new Color(display, 0x6B, 0xA5, 0xD9); - case GEMPLUSH: - return new Color(display, 0xD9, 0x53, 0x9C); - } - } - - /** Main bar inactive background */ - public static final Color MAINBAR_INACTIVE_BACK = getMainbarInactiveBack(); - - private static Color getMainbarInactiveBack() { - switch (THEME) { - default: - case DEFAULT: - return new Color(display, 0xD4, 0xE7, 0xF1); - case GEMPLUSH: - return new Color(display, 0xF1, 0xD1, 0xE8); - } - } - - /** Main bar active text color */ - public static final Color MAINBAR_ACTIVE_TEXTCOLOR = new Color(display, 0x00, 0x00, 0x00); - - /** Main bar inactive text color */ - public static final Color MAINBAR_INACTIVE_TEXTCOLOR = new Color(display, 0x40, 0x40, 0x40); - - /** Drop background color */ - public static final Color DROP_BACK = new Color(display, 0xFF, 0xFF, 0xFF); - - /** Drop border color */ - public static final Color DROP_BORDER_COLOR = MAINBAR_ACTIVE_BACK_LIGHT; - - /** Normal text size */ - public static final int TEXT_SIZE_NORMAL = 12; - - /** Button text size */ - public static final int TEXT_SIZE_BUTTON = 12; - - /** Small text size */ - public static final int TEXT_SIZE_SMALL = 10; - - /** Big text size */ - public static final int TEXT_SIZE_BIG = 14; - - /* Resources */ - - /** Shell icon resource */ - public static final String RES_ICON = "/icons/icon.png"; - - /** Config image resource */ - public static final String RES_IMG_CONFIG = getResImgConfig(); - - private static String getResImgConfig() { - switch (THEME) { - default: - case DEFAULT: - return "/img/config.png"; - case GEMPLUSH: - return "/img/config_p.png"; - } - } - - /** Config inactive image resource */ - public static final String RES_IMG_CONFIG_DISABLED = "/img/config_disabled.png"; - - /** Error image resource */ - public static final String RES_IMG_ERROR = "/img/error.png"; - - /** Card image resource */ - public static final String RES_IMG_CARD = "/img/karte.png"; - - /** Mobile phone image resource */ - public static final String RES_IMG_MOBILE = "/img/handy.png"; - - /** FIDO2 logo resource */ - public static final String RES_IMG_FIDO2 = "/img/fido_logo.png"; - - /** WebAuthN logo resource */ - public static final String RES_IMG_WEBAUTHN = "/img/webauthn-logo.png"; - - /** Package resource path */ - public static String RES_PKG_PATH = "/at/asit/pdfover/gui/"; - - /** Zipped configuration resource */ - public static final String RES_CFG_ZIP = "/cfg/PDFASConfig.zip"; - - /** Accepted certificate resource path */ - public static final String RES_CERT_PATH = "/certificates/"; - - /** Accepted certificate list resource */ - public static final String RES_CERT_LIST = RES_CERT_PATH + "certificates.xml"; - - public static final String LABEL_TAN = "input_tan"; - - public static final String LABEL_SIGN_BTN = "SignButton"; - - public static final String LABEL_PHONE_NUMBER = "handynummer"; - - public static final String LABEL_SIGN_PASS = "signaturpasswort"; - - public static final String LABEL_BTN_IDF = "Button_Identification"; - - /** - * for static analysis; mark a given value as definitely, contractually not null - * (try to avoid its use in performance-critical code, grr java) - */ - public static @Nonnull T ISNOTNULL(T value) { assert(value != null); return value; } - -} diff --git a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/Messages.java b/pdf-over-commons/src/main/java/at/asit/pdfover/commons/Messages.java deleted file mode 100644 index d8f204ea..00000000 --- a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/Messages.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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.commons; - -import java.io.UnsupportedEncodingException; -// Imports -import java.util.HashMap; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -import javax.annotation.Nonnull; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static at.asit.pdfover.commons.Constants.ISNOTNULL; - - -/** - * Localizes string messages for PDFOver GUI - */ -public class Messages { - - /** - * SLF4J Logger instance - **/ - static final Logger log = LoggerFactory.getLogger(Messages.class); - - private static final String BUNDLE_NAME = "at.asit.pdfover.gui.messages"; - - private static HashMap bundles = new HashMap<>(); - - private static Locale currentLocale = getDefaultLocale(); - - private Messages() { - } - - /** - * Get the closest match to the system default Locale out of the supported locales - * @return the default locale - */ - public static @Nonnull Locale getDefaultLocale() { - Locale ld = Locale.getDefault(); - for (Locale l : Constants.SUPPORTED_LOCALES) { - if (l.equals(ld) || l.getLanguage().equals(ld.getLanguage())) - return l; - } - return ISNOTNULL(Constants.SUPPORTED_LOCALES[0]); - } - - /** - * Sets the currently used locals - * @param locale - */ - public static void setLocale(Locale locale) { - currentLocale = locale; - } - - private static ResourceBundle getBundle(Locale locale) { - if(!bundles.containsKey(locale)) { - log.debug("Loading resource bundle for {}", locale); - ResourceBundle tmp = null; - try { - tmp = ResourceBundle.getBundle(BUNDLE_NAME, locale); - log.debug("Received bundle for {}", tmp.getLocale()); - } catch(Exception e) { - log.error("NO RESOURCE BUNDLE FOR {} {}", locale, e); - tmp = ResourceBundle.getBundle(BUNDLE_NAME); - } - if(tmp == null) { - log.error("NO RESOURCE BUNDLE FOR {}", locale); - tmp = ResourceBundle.getBundle(BUNDLE_NAME); - } - bundles.put(locale, tmp); - return tmp; - } - return bundles.get(locale); - } - - /** - * Gets the localized message - * @param key - * @return the localized message - */ - public static @Nonnull String getString(String key) { - return getString(key, currentLocale); - } - - /** - * Gets the localized message - * @param key the key - * @param locale the locale to use - * @return the localized message - */ - public static @Nonnull String getString(String key, Locale locale) { - try { - String value = ISNOTNULL(getBundle(locale).getString(key)); - - /* DIRTY HACK: this recognizes java 8 ("1.8") and older; these versions read .properties files as ISO-8859-1 instead of UTF-8 */ - if (System.getProperty("java.version").startsWith("1.")) - try { value = new String(value.getBytes("ISO-8859-1"), "UTF-8"); } catch (UnsupportedEncodingException e) {} - - log.trace("[{}] {}: {} -> {}", new Object[]{System.getProperty("java.version"), currentLocale, key, value}); - return value; - } catch (MissingResourceException e) { - return '!' + key + '!'; - } - } - - public static @Nonnull String formatString(String key, Object... values) { - return ISNOTNULL(String.format(getString(key), values)); - } -} diff --git a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/Profile.java b/pdf-over-commons/src/main/java/at/asit/pdfover/commons/Profile.java deleted file mode 100644 index d26c8877..00000000 --- a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/Profile.java +++ /dev/null @@ -1,53 +0,0 @@ -package at.asit.pdfover.commons; - -import java.util.Locale; - -public enum Profile { - - SIGNATURBLOCK_SMALL, - AMTSSIGNATURBLOCK, - BASE_LOGO, - INVISIBLE; - - public static int length = Profile.values().length; - - public static Profile getProfile(String name) { - if (SIGNATURBLOCK_SMALL.name().equals(name)) { - return SIGNATURBLOCK_SMALL; - } else if (AMTSSIGNATURBLOCK.name().equals(name)) { - return AMTSSIGNATURBLOCK; - } else if (BASE_LOGO.name().equals(name)) { - return BASE_LOGO; - } else if (INVISIBLE.name().equals(name)){ - return INVISIBLE; - } - return null; - } - - public static Profile getDefaultProfile(){ - return SIGNATURBLOCK_SMALL; - } - - public String getDefaultSignatureBlockNote(Locale locale){ - - if (this == Profile.SIGNATURBLOCK_SMALL){ - return Messages.getString("simple_config.Note_Default_Standard", locale); - } else if (this == Profile.AMTSSIGNATURBLOCK) { - return Messages.getString("simple_config.Note_Default_OfficialSignature", locale); - } else { - return ""; - } - } - - public boolean hasText() { - return ((this == SIGNATURBLOCK_SMALL) || (this == AMTSSIGNATURBLOCK)); - } - - public boolean hasLogo() { - return (this != INVISIBLE); - } - - public boolean isVisibleSignature() { - return (this != INVISIBLE); - } -} diff --git a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/utils/ImageUtil.java b/pdf-over-commons/src/main/java/at/asit/pdfover/commons/utils/ImageUtil.java deleted file mode 100644 index f68f73ec..00000000 --- a/pdf-over-commons/src/main/java/at/asit/pdfover/commons/utils/ImageUtil.java +++ /dev/null @@ -1,290 +0,0 @@ -package at.asit.pdfover.commons.utils; - -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.Iterator; - -import java.awt.image.ComponentColorModel; -import java.awt.image.DirectColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.WritableRaster; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.PaletteData; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.layout.FormAttachment; -import org.eclipse.swt.layout.FormData; -import org.eclipse.swt.layout.FormLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReadParam; -import javax.imageio.ImageReader; -import javax.imageio.stream.ImageInputStream; -import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.drew.imaging.ImageMetadataReader; -import com.drew.imaging.ImageProcessingException; -import com.drew.metadata.Metadata; -import com.drew.metadata.exif.ExifDirectoryBase; -import com.drew.metadata.exif.ExifIFD0Directory; - -class EXIFRotation { - private static final Logger log = LoggerFactory.getLogger(EXIFRotation.class); - /** - * rotate by this times Math.PI / 2 - */ - final int rotationInQuarters; - /** - * whether you should mirror (left-right) the image AFTER rotation - */ - final boolean shouldMirrorLR; - - private EXIFRotation(int rotateQuarters, boolean mirrorLR) { - this.rotationInQuarters = rotateQuarters; - this.shouldMirrorLR = mirrorLR; - } - - public static final EXIFRotation NONE = new EXIFRotation(0, false); - - private static final EXIFRotation[] rotationForIndex = { - /* invalid (0) */ NONE, - /* 1 */ NONE, - /* 2 */ new EXIFRotation(0, true), - /* 3 */ new EXIFRotation(2, false), - /* 4 */ new EXIFRotation(2, true), - /* 5 */ new EXIFRotation(1, true), - /* 6 */ new EXIFRotation(1, false), - /* 7 */ new EXIFRotation(3, true), - /* 8 */ new EXIFRotation(3, false) - }; - - static EXIFRotation For(File file) throws IOException - { - try - { - Metadata metadata = ImageMetadataReader.readMetadata(file); - if (metadata == null) - return NONE; - ExifIFD0Directory metaDir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); - if (metaDir == null) - return NONE; - Integer orientation = metaDir.getInteger(ExifDirectoryBase.TAG_ORIENTATION); - if (orientation == null) - return NONE; - if (rotationForIndex.length <= orientation) - { - log.warn("Invalid orientation {} in EXIF metadata for {}", orientation, file.getName()); - return NONE; - } - return rotationForIndex[orientation]; - } catch (ImageProcessingException e) { - log.error("Failed to read EXIF metadata for {}", file.getName(), e); - return NONE; - } - } -} - -public final class ImageUtil { - - /** - * ImageIO.read, except it honors EXIF rotation metadata - * (which the default, for some reason, does not) - */ - public static final BufferedImage readImageWithEXIFRotation(File input) throws IOException - { - if (input == null) - throw new IllegalArgumentException("input == null"); - if (!input.canRead()) - throw new IllegalArgumentException("cannot read input"); - - ImageInputStream stream = ImageIO.createImageInputStream(input); - if (stream == null) - throw new RuntimeException("Failed to create ImageInputStream for some reason?"); - - Iterator iter = ImageIO.getImageReaders(stream); - if (!iter.hasNext()) - { - stream.close(); - return null; - } - - ImageReader reader = iter.next(); - boolean isJPEG = reader.getFormatName().equals("JPEG"); - ImageReadParam param = reader.getDefaultReadParam(); - reader.setInput(stream, true, false); - BufferedImage image; - try { - image = reader.read(0, param); - } finally { - reader.dispose(); - stream.close(); - } - - if (!isJPEG) - return image; - - EXIFRotation rotation = EXIFRotation.For(input); - if (rotation.rotationInQuarters > 0) - { - boolean isSideways = ((rotation.rotationInQuarters % 2) == 1); - int sourceWidth = image.getWidth(); - int sourceHeight = image.getHeight(); - int targetWidth = isSideways ? sourceHeight : sourceWidth; - int targetHeight = isSideways ? sourceWidth : sourceHeight; - - BufferedImage result = new BufferedImage(targetWidth, targetHeight, image.getType()); - Graphics2D g = result.createGraphics(); - g.translate((targetWidth - sourceWidth)/2, (targetHeight - sourceHeight)/2); - g.rotate(rotation.rotationInQuarters * Math.PI / 2, sourceWidth/2, sourceHeight/2); - g.drawRenderedImage(image, null); - g.dispose(); - image = result; - } - - if (rotation.shouldMirrorLR) - { - int width = image.getWidth(); - int height = image.getHeight(); - BufferedImage result = new BufferedImage(width, height, image.getType()); - Graphics2D g = result.createGraphics(); - g.drawImage(image, width, 0, -width, height, null); - g.dispose(); - image = result; - } - return image; - } - - public static java.awt.Image debugDisplayImage(java.awt.Image image) { - JPanel panel = new JPanel(); - panel.add(new JLabel(new ImageIcon(image))); - JOptionPane.showMessageDialog(null, new JScrollPane(panel)); - return image; - } - - public static org.eclipse.swt.graphics.ImageData debugDisplayImage(org.eclipse.swt.graphics.ImageData image) { - Display display = Display.getDefault(); - Shell shell = new Shell(display, SWT.CLOSE); - shell.setLayout(new FormLayout()); - - Label imgLabel = new Label(shell, SWT.NATIVE); - FormData imgFD = new FormData(); - imgFD.left = new FormAttachment(0); - imgFD.top = new FormAttachment(0); - imgFD.width = image.width; - imgFD.height = image.height; - imgLabel.setLayoutData(imgFD); - imgLabel.setImage(new org.eclipse.swt.graphics.Image(display, image)); - - shell.setSize(image.width + 20, image.height + 60); - - shell.open(); - shell.forceActive(); - return image; - } - - public static org.eclipse.swt.graphics.Image debugDisplayImage(org.eclipse.swt.graphics.Image image) { - debugDisplayImage(image.getImageData()); - return image; - } - - /** - * Convert AWT Image to SWT Image - * - * @param bufferedImage - * @return SWT Image data - */ - public static ImageData convertToSWT(final BufferedImage bufferedImage) { - if (bufferedImage == null) - return null; - - if ((bufferedImage.getWidth() <= 0) || (bufferedImage.getHeight() <= 0)) - return null; - - if (bufferedImage.getColorModel() instanceof DirectColorModel) { - DirectColorModel colorModel = (DirectColorModel) bufferedImage - .getColorModel(); - PaletteData palette = new PaletteData(colorModel.getRedMask(), - colorModel.getGreenMask(), colorModel.getBlueMask()); - ImageData data = new ImageData(bufferedImage.getWidth(), - bufferedImage.getHeight(), colorModel.getPixelSize(), - palette); - WritableRaster raster = bufferedImage.getRaster(); - int[] pixelArray = new int[3]; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - raster.getPixel(x, y, pixelArray); - int pixel = palette.getPixel(new RGB(pixelArray[0], - pixelArray[1], pixelArray[2])); - data.setPixel(x, y, pixel); - } - } - return data; - } else if (bufferedImage.getColorModel() instanceof IndexColorModel) { - IndexColorModel colorModel = (IndexColorModel) bufferedImage - .getColorModel(); - int size = colorModel.getMapSize(); - byte[] reds = new byte[size]; - byte[] greens = new byte[size]; - byte[] blues = new byte[size]; - colorModel.getReds(reds); - colorModel.getGreens(greens); - colorModel.getBlues(blues); - RGB[] rgbs = new RGB[size]; - for (int i = 0; i < rgbs.length; i++) { - rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, - blues[i] & 0xFF); - } - PaletteData palette = new PaletteData(rgbs); - ImageData data = new ImageData(bufferedImage.getWidth(), - bufferedImage.getHeight(), colorModel.getPixelSize(), - palette); - data.transparentPixel = colorModel.getTransparentPixel(); - WritableRaster raster = bufferedImage.getRaster(); - int[] pixelArray = new int[1]; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - raster.getPixel(x, y, pixelArray); - data.setPixel(x, y, pixelArray[0]); - } - } - return data; - } else if (bufferedImage.getColorModel() instanceof ComponentColorModel) { - ComponentColorModel colorModel = (ComponentColorModel)bufferedImage.getColorModel(); - - //ASSUMES: 3 BYTE BGR IMAGE TYPE - - PaletteData palette = new PaletteData(0x0000FF, 0x00FF00,0xFF0000); - ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette); - - //This is valid because we are using a 3-byte Data model with no transparent pixels - data.transparentPixel = -1; - - WritableRaster raster = bufferedImage.getRaster(); - int[] pixelArray = new int[bufferedImage.getColorModel().getNumComponents()]; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - raster.getPixel(x, y, pixelArray); - int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2])); - data.setPixel(x, y, pixel); - if (3 < pixelArray.length) - data.setAlpha(x, y, pixelArray[3]); - } - } - return data; - } - throw new RuntimeException("could not convert image with model " + bufferedImage.getColorModel().getClass().getName()); - } -} -- cgit v1.2.3