private Node getTIFFTree() {
String metadataName = TIFF_FORMAT;
BaselineTIFFTagSet base = BaselineTIFFTagSet.getInstance();
TIFFDirectory dir =
new TIFFDirectory(new TIFFTagSet[] {
base, EXIFParentTIFFTagSet.getInstance()
}, null);
if(sofPresent) {
// sofProcess -> Compression ?
int compression = BaselineTIFFTagSet.COMPRESSION_JPEG;
TIFFField compressionField =
new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_COMPRESSION),
compression);
dir.addTIFFField(compressionField);
// samplePrecision -> BitsPerSample
char[] bitsPerSample = new char[numFrameComponents];
Arrays.fill(bitsPerSample, (char)(samplePrecision & 0xff));
TIFFField bitsPerSampleField =
new TIFFField(
base.getTag(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE),
TIFFTag.TIFF_SHORT,
bitsPerSample.length,
bitsPerSample);
dir.addTIFFField(bitsPerSampleField);
// numLines -> ImageLength
TIFFField imageLengthField =
new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_IMAGE_LENGTH),
numLines);
dir.addTIFFField(imageLengthField);
// samplesPerLine -> ImageWidth
TIFFField imageWidthField =
new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_IMAGE_WIDTH),
samplesPerLine);
dir.addTIFFField(imageWidthField);
// numFrameComponents -> SamplesPerPixel
TIFFField samplesPerPixelField =
new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL),
numFrameComponents);
dir.addTIFFField(samplesPerPixelField);
// componentId -> PhotometricInterpretation + ExtraSamples
IIOMetadataNode chroma = getStandardChromaNode();
if(chroma != null) {
IIOMetadataNode csType =
(IIOMetadataNode)chroma.getElementsByTagName("ColorSpaceType").item(0);
String name = csType.getAttribute("name");
int photometricInterpretation = -1;
if(name.equals("GRAY")) {
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
} else if(name.equals("YCbCr") || name.equals("PhotoYCC")) {
// NOTE: PhotoYCC -> YCbCr
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR;
} else if(name.equals("RGB")) {
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
} else if(name.equals("CMYK") || name.equals("YCCK")) {
// NOTE: YCCK -> CMYK
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CMYK;
}
if(photometricInterpretation != -1) {
TIFFField photometricInterpretationField =
new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION),
photometricInterpretation);
dir.addTIFFField(photometricInterpretationField);
}
if(hasAlpha) {
char[] extraSamples =
new char[] {BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA};
TIFFField extraSamplesField =
new TIFFField(
base.getTag(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES),
TIFFTag.TIFF_SHORT,
extraSamples.length,
extraSamples);
dir.addTIFFField(extraSamplesField);
}
} // chroma != null
} // sofPresent
// JFIF APP0 -> Resolution fields.
if(app0JFIFPresent) {
long[][] xResolution = new long[][] {{Xdensity, 1}};
TIFFField XResolutionField =
new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION),
TIFFTag.TIFF_RATIONAL,
1,
xResolution);
dir.addTIFFField(XResolutionField);
long[][] yResolution = new long[][] {{Ydensity, 1}};
TIFFField YResolutionField =
new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION),
TIFFTag.TIFF_RATIONAL,
1,
yResolution);
dir.addTIFFField(YResolutionField);
int resolutionUnit = BaselineTIFFTagSet.RESOLUTION_UNIT_NONE;
switch(resUnits) {
case JFIF_RESUNITS_ASPECT:
resolutionUnit = BaselineTIFFTagSet.RESOLUTION_UNIT_NONE;
case JFIF_RESUNITS_DPI:
resolutionUnit = BaselineTIFFTagSet.RESOLUTION_UNIT_INCH;
break;
case JFIF_RESUNITS_DPC:
resolutionUnit = BaselineTIFFTagSet.RESOLUTION_UNIT_CENTIMETER;
break;
}
TIFFField ResolutionUnitField =
new TIFFField(base.getTag
(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT),
resolutionUnit);
dir.addTIFFField(ResolutionUnitField);
}
// DQT + DHT -> JPEGTables.
byte[] jpegTablesData = null;
if(dqtPresent || dqtPresent) {
// Determine length of JPEGTables data.
int jpegTablesLength = 2; // SOI
if(dqtPresent) {
Iterator dqts = qtables.iterator();
while(dqts.hasNext()) {
Iterator qtiter = ((List)dqts.next()).iterator();
while(qtiter.hasNext()) {
QTable qt = (QTable)qtiter.next();
jpegTablesLength += 4 + qt.length;
}
}
}
if(dhtPresent) {
Iterator dhts = htables.iterator();
while(dhts.hasNext()) {
Iterator htiter = ((List)dhts.next()).iterator();
while(htiter.hasNext()) {
HuffmanTable ht = (HuffmanTable)htiter.next();
jpegTablesLength += 4 + ht.length;
}
}
}
jpegTablesLength += 2; // EOI
// Allocate space.
jpegTablesData = new byte[jpegTablesLength];
// SOI
jpegTablesData[0] = (byte)0xff;
jpegTablesData[1] = (byte)SOI;
int jpoff = 2;
if(dqtPresent) {
Iterator dqts = qtables.iterator();
while(dqts.hasNext()) {
Iterator qtiter = ((List)dqts.next()).iterator();
while(qtiter.hasNext()) {
jpegTablesData[jpoff++] = (byte)0xff;
jpegTablesData[jpoff++] = (byte)DQT;
QTable qt = (QTable)qtiter.next();
int qtlength = qt.length + 2;
jpegTablesData[jpoff++] =
(byte)((qtlength & 0xff00) >> 8);
jpegTablesData[jpoff++] = (byte)(qtlength & 0xff);
jpegTablesData[jpoff++] =
(byte)(((qt.elementPrecision & 0xf0) << 4) |
(qt.tableID & 0x0f));
int[] table = qt.table.getTable();
int qlen = table.length;
for(int i = 0; i < qlen; i++) {
jpegTablesData[jpoff + zigzag[i]] = (byte)table[i];
}
jpoff += qlen;
}
}
}
if(dhtPresent) {
Iterator dhts = htables.iterator();
while(dhts.hasNext()) {
Iterator htiter = ((List)dhts.next()).iterator();
while(htiter.hasNext()) {
jpegTablesData[jpoff++] = (byte)0xff;
jpegTablesData[jpoff++] = (byte)DHT;
HuffmanTable ht = (HuffmanTable)htiter.next();
int htlength = ht.length + 2;
jpegTablesData[jpoff++] =
(byte)((htlength & 0xff00) >> 8);
jpegTablesData[jpoff++] = (byte)(htlength & 0xff);
jpegTablesData[jpoff++] =
(byte)(((ht.tableClass & 0x0f) << 4) |
(ht.tableID & 0x0f));
short[] lengths = ht.table.getLengths();
int numLengths = lengths.length;
for(int i = 0; i < numLengths; i++) {
jpegTablesData[jpoff++] = (byte)lengths[i];
}
short[] values = ht.table.getValues();
int numValues = values.length;
for(int i = 0; i < numValues; i++) {
jpegTablesData[jpoff++] = (byte)values[i];
}
}
}
}
jpegTablesData[jpoff++] = (byte)0xff;
jpegTablesData[jpoff] = (byte)EOI;
}
if(jpegTablesData != null) {
TIFFField JPEGTablesField =
new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_JPEG_TABLES),
TIFFTag.TIFF_UNDEFINED,
jpegTablesData.length,
jpegTablesData);
dir.addTIFFField(JPEGTablesField);
}
IIOMetadata tiffMetadata = dir.getAsMetadata();
if(exifData != null) {
try {
Iterator tiffReaders =
ImageIO.getImageReadersByFormatName("TIFF");