
org.monte.media.exif.EXIFReader Maven / Gradle / Ivy
The newest version!
package org.monte.media.exif;
import org.monte.media.io.ImageInputStreamAdapter;
import org.monte.media.io.ByteArrayImageInputStream;
import org.monte.media.jpeg.JFIFInputStream;
import org.monte.media.jpeg.JFIFInputStream.Segment;
import org.monte.media.riff.RIFFChunk;
import org.monte.media.riff.RIFFParser;
import org.monte.media.riff.RIFFVisitor;
import org.monte.media.tiff.FileSegment;
import org.monte.media.tiff.BaselineTagSet;
import org.monte.media.tiff.IFDDataType;
import org.monte.media.tiff.IFD;
import org.monte.media.tiff.IFDEntry;
import org.monte.media.math.Rational;
import org.monte.media.tiff.TIFFDirectory;
import org.monte.media.tiff.TIFFField;
import org.monte.media.tiff.TIFFInputStream;
import org.monte.media.tiff.TIFFNode;
import org.monte.media.tiff.TIFFTag;
import org.monte.media.tiff.TagSet;
import org.monte.media.AbortException;
import org.monte.media.ParseException;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Stack;
import java.util.TreeSet;
import javax.imageio.ImageIO;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
public class EXIFReader {
private File file;
private ImageInputStream iin;
private boolean firstImageOnly;
private boolean includeContainerMetadata = true;
private TIFFNode root;
private TreeSet imageOffsets = new TreeSet();
public EXIFReader(File f) {
this.file = f;
}
public EXIFReader(ImageInputStream iin) {
this.iin = iin;
}
public void setFirstImageOnly(boolean b) {
firstImageOnly = b;
}
public boolean isFirstImageOnly() {
return firstImageOnly;
}
public void setIncludeContainerMetadata(boolean b) {
includeContainerMetadata = b;
}
public boolean isIncludeContainerMetadata() {
return includeContainerMetadata;
}
public void read() throws IOException {
if (file != null) {
iin = new FileImageInputStream(file);
}
try {
iin.seek(0);
int magic = iin.readInt();
iin.seek(0);
if (magic == 0x49492a00) {
} else if (magic == 0x4d4d002a) {
} else if (magic == 0x52494646) {
readRIFF(iin);
} else {
readJFIF(iin);
}
} finally {
if (file != null) {
iin.close();
}
}
}
private void readJFIF(ImageInputStream iin) throws IOException {
root = new TIFFDirectory(null, null, -1);
ByteArrayOutputStream exifStream = null;
ArrayList exifSeg = null;
ByteArrayOutputStream mpStream = null;
ArrayList mpSeg = null;
byte[] buf = new byte[512];
JFIFInputStream in = new JFIFInputStream(new BufferedInputStream(new ImageInputStreamAdapter(iin)));
int imageCount = 0;
TIFFDirectory imageNode = null;
Extraction:
for (Segment seg = in.getNextSegment(); seg != null; seg = in.getNextSegment()) {
switch (seg.marker) {
case JFIFInputStream.SOF0_MARKER:
case JFIFInputStream.SOF1_MARKER:
case JFIFInputStream.SOF2_MARKER:
case JFIFInputStream.SOF3_MARKER:
case JFIFInputStream.SOF5_MARKER:
case JFIFInputStream.SOF6_MARKER:
case JFIFInputStream.SOF7_MARKER:
case JFIFInputStream.SOF9_MARKER:
case JFIFInputStream.SOFA_MARKER:
case JFIFInputStream.SOFB_MARKER:
case JFIFInputStream.SOFD_MARKER:
case JFIFInputStream.SOFE_MARKER:
case JFIFInputStream.SOFF_MARKER:
if (includeContainerMetadata && imageNode != null) {
int samplePrecision = in.read() & 0xff;
int numberOfLines = ((in.read() & 0xff) << 8) | (in.read());
int samplesPerLine = ((in.read() & 0xff) << 8) | (in.read());
int numberOfComponents = in.read() & 0xff;
TIFFDirectory dir = new TIFFDirectory(BaselineTagSet.getInstance(), null, 0);
imageNode.add(dir);
dir.add(new TIFFField(BaselineTagSet.BitsPerSample, samplePrecision));
dir.add(new TIFFField(BaselineTagSet.ImageWidth, samplesPerLine));
dir.add(new TIFFField(BaselineTagSet.ImageHeight, numberOfLines));
}
break;
case JFIFInputStream.SOI_MARKER:
imageNode = new TIFFDirectory(ImageTagSet.getInstance(), null, imageCount++, 0, in.getStreamPosition(), new FileSegment(seg.offset, seg.length));
root.add(imageNode);
exifStream = new ByteArrayOutputStream();
exifSeg = new ArrayList();
mpStream = new ByteArrayOutputStream();
mpSeg = new ArrayList();
break;
case JFIFInputStream.APP1_MARKER:
try {
in.read(buf, 0, 6);
if (!new String(buf, 0, 6, "ASCII").equals("Exif\u0000\u0000")) {
continue;
}
} catch (IOException e) {
continue;
}
exifSeg.add(new FileSegment(seg.offset + 6, seg.length - 6));
for (int count = in.read(buf); count != -1; count = in.read(buf)) {
exifStream.write(buf, 0, count);
}
break;
case JFIFInputStream.APP2_MARKER:
try {
in.read(buf, 0, 4);
if (!new String(buf, 0, 4, "ASCII").equals("MPF\u0000")) {
continue;
}
} catch (IOException e) {
continue;
}
mpSeg.add(new FileSegment(seg.offset + 4, seg.length - 4));
for (int count = in.read(buf); count != -1; count = in.read(buf)) {
mpStream.write(buf, 0, count);
}
break;
case JFIFInputStream.EOI_MARKER:
break;
case JFIFInputStream.SOS_MARKER:
if (exifStream.size() > 0) {
TIFFInputStream tin = new TIFFInputStream(new ByteArrayImageInputStream(exifStream.toByteArray()));
readTIFFIFD(tin, imageNode, exifSeg);
exifStream.reset();
}
if (mpStream.size() > 0) {
TIFFInputStream tin = new TIFFInputStream(new ByteArrayImageInputStream(mpStream.toByteArray()));
readMPFIFD(tin, imageNode, null, mpSeg);
mpStream.reset();
}
if (firstImageOnly) {
break Extraction;
} else {
long streamPosition = in.getStreamPosition();
Long nextImage = imageOffsets.ceiling(streamPosition);
if (nextImage == null) {
break Extraction;
} else {
in.skipFully(nextImage - streamPosition);
}
}
break;
}
}
}
private void readRIFF(ImageInputStream iin) throws IOException {
root = new TIFFDirectory(null, null, -1);
RIFFParser parser = new RIFFParser();
final int hdrl_ID = RIFFParser.stringToID("hdrl");
final int strl_ID = RIFFParser.stringToID("strl");
final int strh_ID = RIFFParser.stringToID("strh");
final int strd_ID = RIFFParser.stringToID("strd");
final int AVI_ID = RIFFParser.stringToID("AVI ");
final int AVIF_ID = RIFFParser.stringToID("AVIF");
final int RIFF_ID = RIFFParser.stringToID("RIFF");
final int LIST_ID = RIFFParser.stringToID("LIST");
parser.declareDataChunk(strl_ID, strh_ID);
parser.declareDataChunk(strl_ID, strd_ID);
parser.declareGroupChunk(AVI_ID, RIFF_ID);
parser.declareGroupChunk(hdrl_ID, LIST_ID);
parser.declareGroupChunk(strl_ID, LIST_ID);
try {
parser.parse(new ImageInputStreamAdapter(iin), new RIFFVisitor() {
private boolean isAVI;
private int trackCount = 0;
private TIFFDirectory trackNode;
@Override
public void enterGroup(RIFFChunk group) throws ParseException, AbortException {
if (group.getType() == AVI_ID) {
isAVI = true;
}
}
@Override
public void leaveGroup(RIFFChunk group) throws ParseException, AbortException {
if (group.getType() == AVI_ID) {
isAVI = false;
}
if (isAVI && group.getType() == hdrl_ID) {
throw new AbortException();
}
}
@Override
public void visitChunk(RIFFChunk group, RIFFChunk chunk) throws ParseException, AbortException {
if (chunk.getID() == strh_ID) {
trackCount++;
} else if (chunk.getID() == strd_ID) {
trackNode = new TIFFDirectory(TrackTagSet.getInstance(), null, trackCount - 1, null, null, new FileSegment(chunk.getScan(), chunk.getSize()));
root.add(trackNode);
ByteArrayImageInputStream in = new ByteArrayImageInputStream(chunk.getData(), 8, (int) chunk.getSize() - 8, ByteOrder.LITTLE_ENDIAN);
try {
TIFFInputStream tin = new TIFFInputStream(in, ByteOrder.LITTLE_ENDIAN, 0);
ArrayList tiffSeg = new ArrayList();
tiffSeg.add(new FileSegment(chunk.getScan() + 8, chunk.getSize() - 8));
readTIFFIFD(tin, trackNode, tiffSeg);
} catch (IOException ex) {
ParseException e = new ParseException("Error parsing AVI strd chunk.");
e.initCause(ex);
throw e;
} finally {
in.close();
}
if (isFirstImageOnly()) {
throw new AbortException();
}
}
}
@Override
public boolean enteringGroup(RIFFChunk group) {
return true;
}
});
} catch (ParseException ex) {
ex.printStackTrace();
} catch (AbortException ex) {
}
}
public void readAVIstrdChunk(byte[] data) throws IOException {
int track = 0;
int scan = 0;
root = new TIFFDirectory(null, null, -1);
TIFFDirectory trackNode = new TIFFDirectory(TrackTagSet.getInstance(), null, track, null, null, new FileSegment(0, data.length));
root.add(trackNode);
ByteArrayImageInputStream in = new ByteArrayImageInputStream(data, 8, (int) data.length - 8, ByteOrder.LITTLE_ENDIAN);
TIFFInputStream tin = new TIFFInputStream(in, ByteOrder.LITTLE_ENDIAN, 0);
ArrayList tiffSeg = new ArrayList();
tiffSeg.add(new FileSegment(scan + 8, data.length - 8));
readTIFFIFD(tin, trackNode, tiffSeg);
}
private void readTIFFIFD(TIFFInputStream tin, TIFFDirectory parent, ArrayList tiffSeg) throws IOException {
int count = 0;
TagSet tagSet = BaselineTagSet.getInstance();
for (IFD ifd = tin.readIFD(tin.getFirstIFDOffset(), true, true); ifd != null; ifd = tin.readIFD(ifd.getNextOffset())) {
TIFFDirectory ifdNode = new TIFFDirectory(tagSet, null, count++, ifd, null, tiffSeg);
parent.add(ifdNode);
long thumbnailOffset = 0;
long thumbnailLength = 0;
int entryCount = 0;
for (IFDEntry entry : ifd.getEntries()) {
switch (entry.getTagNumber()) {
case BaselineTagSet.TAG_EXIF:
readExifIFD(tin, entry.getValueOffset(), ifdNode, entry, tiffSeg);
break;
case BaselineTagSet.TAG_GPS:
readGPSIFD(tin, entry.getValueOffset(), ifdNode, entry, tiffSeg);
break;
case BaselineTagSet.TAG_Interoperability:
readInteropIFD(tin, entry.getValueOffset(), ifdNode, entry, tiffSeg);
break;
case BaselineTagSet.TAG_JPEGInterchangeFormat:
thumbnailOffset = entry.getValueOffset();
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
break;
case BaselineTagSet.TAG_JPEGInterchangeFormatLength:
thumbnailLength = entry.getValueOffset();
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
break;
default:
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
break;
}
entryCount++;
}
if (thumbnailOffset > 0 && thumbnailLength > 0) {
byte[] buf = new byte[(int) thumbnailLength];
tin.read(thumbnailOffset, buf, 0, (int) thumbnailLength);
IFDEntry entry = new IFDEntry(BaselineTagSet.TAG_JPEGThumbnailImage, IFDDataType.UNDEFINED.getTypeNumber(), thumbnailLength, thumbnailOffset, -1);
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
}
}
}
private void readExifIFD(TIFFInputStream tin, long offset, TIFFDirectory parent, IFDEntry parentEntry, ArrayList tiffSeg) throws IOException {
int count = 0;
TagSet tagSet = EXIFTagSet.getInstance();
for (IFD ifd = tin.readIFD(offset); ifd != null; ifd = tin.readIFD(ifd.getNextOffset())) {
TIFFDirectory ifdNode = new TIFFDirectory(tagSet, BaselineTagSet.getInstance().getTag(BaselineTagSet.TAG_EXIF), count++, ifd, parentEntry, tiffSeg);
parent.add(ifdNode);
int entryCount = 0;
for (IFDEntry entry : ifd.getEntries()) {
if (entry.getTagNumber() == EXIFTagSet.Interoperability.getNumber()) {
readInteropIFD(tin, entry.getValueOffset(), ifdNode, entry, tiffSeg);
} else if (entry.getTagNumber() == EXIFTagSet.MakerNote.getNumber()) {
if (readMakerNoteIFD(tin, entry.getValueOffset(), ifdNode, entry, tiffSeg)) {
break;
} else {
}
} else {
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
}
entryCount++;
}
}
}
private void readGPSIFD(TIFFInputStream tin, long offset, TIFFDirectory parent, IFDEntry parentEntry, ArrayList tiffSeg) throws IOException {
int count = 0;
TagSet tagSet = GPSTagSet.getInstance();
for (IFD ifd = tin.readIFD(offset); ifd != null; ifd = tin.readIFD(ifd.getNextOffset())) {
TIFFDirectory ifdNode = new TIFFDirectory(tagSet, BaselineTagSet.getInstance().getTag(BaselineTagSet.TAG_GPS), count++, ifd, parentEntry, tiffSeg);
parent.add(ifdNode);
int entryCount = 0;
for (IFDEntry entry : ifd.getEntries()) {
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
entryCount++;
}
}
}
private void readInteropIFD(TIFFInputStream tin, long offset, TIFFDirectory parent, IFDEntry parentEntry, ArrayList tiffSeg) throws IOException {
int count = 0;
TagSet tagSet = InteroperabilityTagSet.getInstance();
for (IFD ifd = tin.readIFD(offset); ifd != null; ifd = tin.readIFD(ifd.getNextOffset())) {
TIFFDirectory ifdNode = new TIFFDirectory(tagSet, BaselineTagSet.getInstance().getTag(BaselineTagSet.TAG_Interoperability), count++, ifd, parentEntry, tiffSeg);
parent.add(ifdNode);
int entryCount = 0;
for (IFDEntry entry : ifd.getEntries()) {
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
entryCount++;
}
}
}
private void readMPFIFD(TIFFInputStream tin, TIFFDirectory parent, IFDEntry parentEntry, ArrayList tiffSeg) throws IOException {
int count = 0;
TagSet tagSet = MPFTagSet.getInstance();
for (IFD ifd = tin.readIFD(tin.getFirstIFDOffset()); ifd != null; ifd = tin.readIFD(ifd.getNextOffset())) {
TIFFDirectory ifdNode = new TIFFDirectory(tagSet, null, count++, ifd, parentEntry, tiffSeg);
parent.add(ifdNode);
int entryCount = 0;
for (IFDEntry entry : ifd.getEntries()) {
switch (entry.getTagNumber()) {
case MPFTagSet.TAG_MPEntryInformation:
readMPEntries(tin, entry, ifdNode, tiffSeg);
break;
default:
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
entryCount++;
break;
}
}
}
}
private void readMPEntries(TIFFInputStream tin, IFDEntry mpEntryInformation, TIFFDirectory parent, ArrayList tiffSeg) throws IOException {
byte[] buf = (byte[]) mpEntryInformation.readData(tin);
TagSet tagSet = MPEntryTagSet.getInstance();
ByteArrayImageInputStream in = new ByteArrayImageInputStream(buf);
ByteOrder bo = tin.getByteOrder();
in.setByteOrder(bo);
int numImages = (int) mpEntryInformation.getLength() / 16;
try {
for (int imageCount = 0; imageCount < numImages; imageCount++) {
TIFFDirectory ifdNode = new TIFFDirectory(tagSet, tagSet.getTag(MPFTagSet.TAG_MPEntryInformation), imageCount, mpEntryInformation.getValueOffset(), 16 * imageCount, tiffSeg);
parent.add(ifdNode);
int imageAttr = in.readInt();
short dpif = (short) (imageAttr >>> 31);
ifdNode.add(new TIFFField(tagSet.getTag(MPEntryTagSet.TAG_DependentParentImageFlag), dpif));
short dcif = (short) ((imageAttr >>> 30) & 1);
ifdNode.add(new TIFFField(tagSet.getTag(MPEntryTagSet.TAG_DependentChildImageFlag), dcif));
short rif = (short) ((imageAttr >>> 29) & 1);
ifdNode.add(new TIFFField(tagSet.getTag(MPEntryTagSet.TAG_RepresentativeImageFlag), rif));
short idf = (short) ((imageAttr >>> 24) & 7);
ifdNode.add(new TIFFField(tagSet.getTag(MPEntryTagSet.TAG_ImageDataFormat), idf));
long mptc = (imageAttr & 0xffffffL);
ifdNode.add(new TIFFField(tagSet.getTag(MPEntryTagSet.TAG_MPTypeCode), mptc));
long imageSize = in.readInt() & 0xffffffffL;
ifdNode.add(new TIFFField(tagSet.getTag(MPEntryTagSet.TAG_IndividualImageSize), imageSize));
long imageOffset = in.readInt() & 0xffffffffL;
ifdNode.add(new TIFFField(tagSet.getTag(MPEntryTagSet.TAG_IndividualImageDataOffset), imageOffset));
imageOffsets.add(imageOffset);
int dependentImageEntryNumber = in.readUnsignedShort();
ifdNode.add(new TIFFField(tagSet.getTag(MPEntryTagSet.TAG_DependentImage1EntryNumber), dependentImageEntryNumber));
dependentImageEntryNumber = in.readUnsignedShort();
ifdNode.add(new TIFFField(tagSet.getTag(MPEntryTagSet.TAG_DependentImage2EntryNumber), dependentImageEntryNumber));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
in.close();
}
}
private boolean readMakerNoteIFD(TIFFInputStream tin, long offset, TIFFDirectory parent, IFDEntry parentEntry, ArrayList tiffSeg) throws IOException {
try {
String magic = tin.readASCII(offset, 10);
if (magic.equals("FUJIFILM\u000c")) {
return readFujifilmMakerNoteIFD(tin, offset, parent, parentEntry, tiffSeg);
} else if (magic.equals("SONY DSC ")) {
return readSonyMakerNoteIFD(tin, offset, parent, parentEntry, tiffSeg);
}
} catch (IOException e) {
return false;
}
return false;
}
private boolean readFujifilmMakerNoteIFD(TIFFInputStream tin, long offset, TIFFDirectory parent, IFDEntry parentEntry, ArrayList tiffSeg) throws IOException {
int count = 0;
TagSet tagSet = FujifilmMakerNoteTagSet.getInstance();
try {
for (IFD ifd = tin.readIFD(offset + 12); ifd != null; ifd = tin.readIFD(ifd.getNextOffset())) {
TIFFDirectory ifdNode = new TIFFDirectory(tagSet, EXIFTagSet.MakerNote, count++, ifd, parentEntry, tiffSeg);
parent.add(ifdNode);
int entryCount = 0;
for (IFDEntry entry : ifd.getEntries()) {
entry.setIFDOffset(offset);
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
entryCount++;
}
}
} catch (IOException e) {
return false;
}
return true;
}
private boolean readSonyMakerNoteIFD(TIFFInputStream tin, long offset, TIFFDirectory parent, IFDEntry parentEntry, ArrayList tiffSeg) throws IOException {
int count = 0;
TagSet tagSet = SonyMakerNoteTagSet.getInstance();
try {
for (IFD ifd = tin.readIFD(offset + 12); ifd != null; ifd = tin.readIFD(ifd.getNextOffset())) {
TIFFDirectory ifdNode = new TIFFDirectory(tagSet, EXIFTagSet.MakerNote, count++, ifd, parentEntry, tiffSeg);
parent.add(ifdNode);
int entryCount = 0;
for (IFDEntry entry : ifd.getEntries()) {
ifdNode.add(new TIFFField(tagSet.getTag(entry.getTagNumber()), entry.readData(tin), entry));
entryCount++;
}
}
} catch (IOException e) {
return false;
}
return true;
}
public TIFFNode getMetaDataTree() {
return root;
}
public int getImageCount() {
return root == null ? -1 : root.getChildCount();
}
public ArrayList getDirectories(int image, TagSet tagSet) {
ArrayList dirs = new ArrayList();
Stack stack = new Stack();
stack.push((TIFFDirectory) getMetaDataTree().getChildAt(image));
while (!stack.isEmpty()) {
TIFFDirectory dir = stack.pop();
for (TIFFNode node : dir.getChildren()) {
if (node instanceof TIFFDirectory) {
TIFFDirectory dirNode = (TIFFDirectory) node;
if (dirNode.getTagSet() == tagSet) {
dirs.add(0, dirNode);
} else {
stack.push(dirNode);
}
}
}
}
return dirs;
}
public ArrayList getThumbnails(boolean suppressException) throws IOException {
ArrayList thumbnails = new ArrayList();
Stack stack = new Stack();
stack.push((TIFFDirectory) getMetaDataTree());
if (stack.peek() == null) {
return thumbnails;
}
while (!stack.isEmpty()) {
TIFFDirectory dir = stack.pop();
for (TIFFNode node : dir.getChildren()) {
if (node instanceof TIFFDirectory) {
stack.push((TIFFDirectory) node);
} else if (node instanceof TIFFField) {
TIFFField field = (TIFFField) node;
if (field.getTag() == BaselineTagSet.JPEGThumbnailImage) {
try {
thumbnails.add(0, ImageIO.read(new ByteArrayImageInputStream((byte[]) field.getData())));
} catch (IOException e) {
if (!suppressException) {
throw e;
}
}
}
}
}
}
return thumbnails;
}
public HashMap getMetaDataMap() {
HashMap m = new HashMap();
for (Iterator i = root.preorderIterator(); i.hasNext();) {
TIFFNode node = i.next();
if (node instanceof TIFFField) {
m.put(node.getTag(), (TIFFField) node);
}
}
return m;
}
public IIOMetadataNode getIIOMetadataTree(String formatName, int imageIndex) {
if (formatName != null && !formatName.equals("com_sun_media_imageio_plugins_tiff_image_1.0")) {
throw new IllegalArgumentException("Unsupported formatName:" + formatName);
}
IIOMetadataNode iioRoot = new IIOMetadataNode("com_sun_media_imageio_plugins_tiff_image_1.0");
TIFFNode imageRoot = root.getChildAt(imageIndex);
for (TIFFNode node : imageRoot.getChildren()) {
addIIOMetadataNode(iioRoot, node);
}
return iioRoot;
}
private void addIIOMetadataNode(IIOMetadataNode iioParent, TIFFNode node) {
if (node instanceof TIFFDirectory) {
TIFFDirectory dir = (TIFFDirectory) node;
IIOMetadataNode iioNode = new IIOMetadataNode("TIFFIFD");
TagSet tagSet = dir.getTagSet();
iioNode.setAttribute("tagSets", dir == null ? "" : tagSet.getName());
if (dir.getTag() != null) {
iioNode.setAttribute("parentTagNumber", Integer.toString(dir.getTagNumber()));
iioNode.setAttribute("parentTagName", dir.getTag().getName());
}
iioParent.appendChild(iioNode);
for (int i = 0; i < node.getChildCount(); i++) {
addIIOMetadataNode(iioNode, node.getChildAt(i));
}
} else if (node instanceof TIFFField) {
TIFFField field = (TIFFField) node;
IIOMetadataNode iioNode = new IIOMetadataNode("TIFFField");
iioNode.setAttribute("number", Integer.toString(field.getTagNumber()));
if (field.getTagName() != null && !field.getTagName().equals("unknown")) {
iioNode.setAttribute("name", field.getTagName());
}
IIOMetadataNode iioSequence = null;
String description = field.getDescription();
switch (field.getType()) {
case ASCII: {
iioSequence = new IIOMetadataNode("TIFFAsciis");
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFAscii");
iioValue.setAttribute("value", (String) field.getData());
iioSequence.appendChild(iioValue);
break;
}
case BYTE: {
iioSequence = new IIOMetadataNode("TIFFBytes");
short[] value = (field.getData() instanceof Short) ? new short[]{(Short) field.getData()} : (short[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFByte");
iioValue.setAttribute("value", Short.toString(value[i]));
iioSequence.appendChild(iioValue);
if (i == 0 && description != null) {
iioValue.setAttribute("description", description);
}
}
break;
}
case SBYTE: {
iioSequence = new IIOMetadataNode("TIFFSBytes");
byte[] value = (field.getData() instanceof Byte) ? new byte[]{(Byte) field.getData()} : (byte[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFSByte");
iioValue.setAttribute("value", Byte.toString(value[i]));
iioSequence.appendChild(iioValue);
if (i == 0 && description != null) {
iioValue.setAttribute("description", description);
}
}
break;
}
case DOUBLE: {
iioSequence = new IIOMetadataNode("TIFFDoubles");
double[] value = (field.getData() instanceof Double) ? new double[]{(Double) field.getData()} : (double[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFDouble");
iioValue.setAttribute("value", Double.toString(value[i]));
iioSequence.appendChild(iioValue);
}
break;
}
case FLOAT: {
iioSequence = new IIOMetadataNode("TIFFFloats");
float[] value = (field.getData() instanceof Float) ? new float[]{(Float) field.getData()} : (float[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFFloat");
iioValue.setAttribute("value", Double.toString(value[i]));
iioSequence.appendChild(iioValue);
if (i == 0 && description != null) {
iioValue.setAttribute("description", description);
}
}
break;
}
case LONG: {
iioSequence = new IIOMetadataNode("TIFFLongs");
long[] value = (field.getData() instanceof Long) ? new long[]{(Long) field.getData()} : (long[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFLong");
iioValue.setAttribute("value", Long.toString(value[i]));
iioSequence.appendChild(iioValue);
if (i == 0 && description != null) {
iioValue.setAttribute("description", description);
}
}
break;
}
case SLONG: {
iioSequence = new IIOMetadataNode("TIFFSLongs");
int[] value = (field.getData() instanceof Integer) ? new int[]{(Integer) field.getData()} : (int[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFSLong");
iioValue.setAttribute("value", Integer.toString(value[i]));
iioSequence.appendChild(iioValue);
if (i == 0 && description != null) {
iioValue.setAttribute("description", description);
}
}
break;
}
case RATIONAL: {
iioSequence = new IIOMetadataNode("TIFFRationals");
Rational[] value = (field.getData() instanceof Rational) ? new Rational[]{(Rational) field.getData()} : (Rational[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFRational");
iioValue.setAttribute("value", Long.toString(value[i].getNumerator()) + "/" + Long.toString(value[i].getDenominator()));
iioSequence.appendChild(iioValue);
if (i == 0 && description != null) {
iioValue.setAttribute("description", description);
}
}
break;
}
case SRATIONAL: {
iioSequence = new IIOMetadataNode("TIFFSRationals");
Rational[] value = (field.getData() instanceof Rational) ? new Rational[]{(Rational) field.getData()} : (Rational[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFSRational");
iioValue.setAttribute("value", Long.toString(value[i].getNumerator()) + "/" + Long.toString(value[i].getDenominator()));
iioSequence.appendChild(iioValue);
if (i == 0 && description != null) {
iioValue.setAttribute("description", description);
}
}
break;
}
case SHORT: {
iioSequence = new IIOMetadataNode("TIFFShorts");
int[] value = (field.getData() instanceof Integer) ? new int[]{(Integer) field.getData()} : (int[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFShort");
iioValue.setAttribute("value", Integer.toString(value[i]));
iioSequence.appendChild(iioValue);
if (i == 0 && description != null) {
iioValue.setAttribute("description", description);
}
}
break;
}
case SSHORT: {
iioSequence = new IIOMetadataNode("TIFFSShorts");
short[] value = (field.getData() instanceof Short) ? new short[]{(Short) field.getData()} : (short[]) field.getData();
for (int i = 0; i < value.length; i++) {
IIOMetadataNode iioValue = new IIOMetadataNode("TIFFSShort");
iioValue.setAttribute("value", Short.toString(value[i]));
iioSequence.appendChild(iioValue);
if (i == 0 && description != null) {
iioValue.setAttribute("description", description);
}
}
break;
}
case UNDEFINED: {
iioSequence = new IIOMetadataNode("TIFFUndefined");
byte[] value = (field.getData() instanceof Byte) ? new byte[]{(Byte) field.getData()} : (byte[]) field.getData();
StringBuilder iioValue = new StringBuilder();
for (int i = 0; i < value.length; i++) {
if (i != 0) {
iioValue.append(',');
}
iioValue.append(Integer.toString(value[i] & 0xff));
}
iioSequence.setAttribute("value", iioValue.toString());
if (description != null) {
iioSequence.setAttribute("description", description);
}
break;
}
}
if (iioSequence != null) {
iioNode.appendChild(iioSequence);
}
iioParent.appendChild(iioNode);
}
}
public IIOMetadata getIIOMetadata(int i) {
throw new UnsupportedOperationException("Not yet implemented");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy