package er.attachment.metadata; import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; import javax.imageio.stream.ImageInputStream; import org.w3c.dom.Node; import com.drew.lang.ByteArrayReader; import com.drew.lang.SequentialByteArrayReader; import com.drew.metadata.Metadata; import com.drew.metadata.exif.ExifIFD0Directory; import com.drew.metadata.exif.ExifReader; import com.drew.metadata.iptc.IptcDirectory; import com.drew.metadata.iptc.IptcReader; public class JAIMetadataParser implements IERMetadataParser { public static int EXIF = 0xE1; public static int IPTC = 0xED; private static Set<String> UNWANTED = new HashSet<>(); static { JAIMetadataParser.UNWANTED.add("com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader"); JAIMetadataParser.UNWANTED.add("com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageWriter"); } public ERMetadataDirectorySet parseMetadata(File importFile) throws ERMetadataParserException { try { ERMetadataDirectorySet rawAssetMetadata = new ERMetadataDirectorySet(); try (ImageInputStream imageInputStream = ImageIO.createImageInputStream(importFile)) { Iterator imageReadersIter = ImageIO.getImageReaders(imageInputStream); while (imageReadersIter.hasNext()) { ImageReader imageReader = (ImageReader) imageReadersIter.next(); imageReader.setInput(imageInputStream); rawAssetMetadata.setWidth(imageReader.getWidth(0)); rawAssetMetadata.setHeight(imageReader.getHeight(0)); IIOMetadata metadata = imageReader.getImageMetadata(0); if (metadata != null) { Node metadataTree = metadata.getAsTree(metadata.getNativeMetadataFormatName()); if (metadataTree != null) { IptcDirectory iptcDirectory = getIptcDirectory(metadataTree); if (iptcDirectory != null) { ERParsedMetadataDirectory iptcMetadataDirectory = new ERParsedMetadataDirectory(IERMetadataDirectory.IPTC); DrewMetadataParser.fillInParsedMetadataDirectoryFromDrewMetadata(iptcMetadataDirectory, iptcDirectory); rawAssetMetadata.addMetadata(iptcMetadataDirectory); } ExifIFD0Directory exifDirectory = getExifDirectory(metadataTree); if (exifDirectory != null) { ERParsedMetadataDirectory exifMetadataDirectory = new ERParsedMetadataDirectory(IERMetadataDirectory.EXIF); DrewMetadataParser.fillInParsedMetadataDirectoryFromDrewMetadata(exifMetadataDirectory, exifDirectory); rawAssetMetadata.addMetadata(exifMetadataDirectory); } } } } } return rawAssetMetadata; } catch (IOException e) { throw new ERMetadataParserException("Failed to parse metadata.", e); } } private ExifIFD0Directory getExifDirectory(Node node) { if ("unknown".equals(node.getNodeName())) { if (Integer.parseInt(node.getAttributes().getNamedItem("MarkerTag").getNodeValue()) == EXIF) { ByteArrayReader reader = new ByteArrayReader((byte[]) ((IIOMetadataNode) node).getUserObject()); Metadata metadata = new Metadata(); new ExifReader().extract(reader, metadata); return metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); } } Node child = node.getFirstChild(); while (child != null) { ExifIFD0Directory directory = getExifDirectory(child); if (directory != null) { return directory; } child = child.getNextSibling(); } return null; } private IptcDirectory getIptcDirectory(Node node) { if ("unknown".equals(node.getNodeName())) { if (Integer.parseInt(node.getAttributes().getNamedItem("MarkerTag").getNodeValue()) == IPTC) { byte[] tagBytes = (byte[]) ((IIOMetadataNode) node).getUserObject(); Metadata metadata = new Metadata(); new IptcReader().extract(new SequentialByteArrayReader(tagBytes), metadata, tagBytes.length); return metadata.getFirstDirectoryOfType(IptcDirectory.class); } } Node child = node.getFirstChild(); while (child != null) { IptcDirectory directory = getIptcDirectory(child); if (directory != null) { return directory; } child = child.getNextSibling(); } return null; } }