return charArray;
}
private void mergeStandardTree(Node root)
throws IIOInvalidTreeException {
TIFFField f;
TIFFTag tag;
Node node = root;
if (!node.getNodeName()
.equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
fatal(node, "Root must be " +
IIOMetadataFormatImpl.standardMetadataFormatName);
}
// Obtain the sample format and set the palette flag if appropriate.
String sampleFormat = null;
Node dataNode = getChildNode(root, "Data");
boolean isPaletteColor = false;
if(dataNode != null) {
Node sampleFormatNode = getChildNode(dataNode, "SampleFormat");
if(sampleFormatNode != null) {
sampleFormat = getAttribute(sampleFormatNode, "value");
isPaletteColor = sampleFormat.equals("Index");
}
}
// If palette flag not set check for palette.
if(!isPaletteColor) {
Node chromaNode = getChildNode(root, "Chroma");
if(chromaNode != null &&
getChildNode(chromaNode, "Palette") != null) {
isPaletteColor = true;
}
}
node = node.getFirstChild();
while (node != null) {
String name = node.getNodeName();
if (name.equals("Chroma")) {
String colorSpaceType = null;
String blackIsZero = null;
boolean gotPalette = false;
Node child = node.getFirstChild();
while (child != null) {
String childName = child.getNodeName();
if (childName.equals("ColorSpaceType")) {
colorSpaceType = getAttribute(child, "name");
} else if (childName.equals("NumChannels")) {
tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL);
int samplesPerPixel = isPaletteColor ?
1 : Integer.parseInt(getAttribute(child, "value"));
f = new TIFFField(tag, samplesPerPixel);
rootIFD.addTIFFField(f);
} else if (childName.equals("BlackIsZero")) {
blackIsZero = getAttribute(child, "value");
} else if (childName.equals("Palette")) {
Node entry = child.getFirstChild();
HashMap palette = new HashMap();
int maxIndex = -1;
while(entry != null) {
String entryName = entry.getNodeName();
if(entryName.equals("PaletteEntry")) {
String idx = getAttribute(entry, "index");
int id = Integer.parseInt(idx);
if(id > maxIndex) {
maxIndex = id;
}
char red =
(char)Integer.parseInt(getAttribute(entry,
"red"));
char green =
(char)Integer.parseInt(getAttribute(entry,
"green"));
char blue =
(char)Integer.parseInt(getAttribute(entry,
"blue"));
palette.put(new Integer(id),
new char[] {red, green, blue});
gotPalette = true;
}
entry = entry.getNextSibling();
}
if(gotPalette) {
int mapSize = maxIndex + 1;
int paletteLength = 3*mapSize;
char[] paletteEntries = new char[paletteLength];
Iterator paletteIter = palette.keySet().iterator();
while(paletteIter.hasNext()) {
Integer index = (Integer)paletteIter.next();
char[] rgb = (char[])palette.get(index);
int idx = index.intValue();
paletteEntries[idx] =
(char)((rgb[0]*65535)/255);
paletteEntries[mapSize + idx] =
(char)((rgb[1]*65535)/255);
paletteEntries[2*mapSize + idx] =
(char)((rgb[2]*65535)/255);
}
tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_COLOR_MAP);
f = new TIFFField(tag, TIFFTag.TIFF_SHORT,
paletteLength, paletteEntries);
rootIFD.addTIFFField(f);
}
}
child = child.getNextSibling();
}
int photometricInterpretation = -1;
if((colorSpaceType == null || colorSpaceType.equals("GRAY")) &&
blackIsZero != null &&
blackIsZero.equalsIgnoreCase("FALSE")) {
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
} else if(colorSpaceType != null) {
if(colorSpaceType.equals("GRAY")) {
boolean isTransparency = false;
if(root instanceof IIOMetadataNode) {
IIOMetadataNode iioRoot = (IIOMetadataNode)root;
NodeList siNodeList =
iioRoot.getElementsByTagName("SubimageInterpretation");
if(siNodeList.getLength() == 1) {
Node siNode = siNodeList.item(0);
String value = getAttribute(siNode, "value");
if(value.equals("TransparencyMask")) {
isTransparency = true;
}
}
}
if(isTransparency) {
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_TRANSPARENCY_MASK;
} else {
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
}
} else if(colorSpaceType.equals("RGB")) {
photometricInterpretation =
gotPalette ?
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_PALETTE_COLOR :
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
} else if(colorSpaceType.equals("YCbCr")) {
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR;
} else if(colorSpaceType.equals("CMYK")) {
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CMYK;
} else if(colorSpaceType.equals("Lab")) {
photometricInterpretation =
BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CIELAB;
}
}
if(photometricInterpretation != -1) {
tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION);
f = new TIFFField(tag, photometricInterpretation);
rootIFD.addTIFFField(f);
}
} else if (name.equals("Compression")) {
Node child = node.getFirstChild();
while (child != null) {
String childName = child.getNodeName();
if (childName.equals("CompressionTypeName")) {
int compression = -1;
String compressionTypeName =
getAttribute(child, "value");
if(compressionTypeName.equalsIgnoreCase("None")) {
compression =
BaselineTIFFTagSet.COMPRESSION_NONE;
} else {
String[] compressionNames =
TIFFImageWriter.compressionTypes;
for(int i = 0; i < compressionNames.length; i++) {
if(compressionNames[i].equalsIgnoreCase(compressionTypeName)) {
compression =
TIFFImageWriter.compressionNumbers[i];
break;
}
}
}
if(compression != -1) {
tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_COMPRESSION);
f = new TIFFField(tag, compression);
rootIFD.addTIFFField(f);
// Lossless is irrelevant.
}
}
child = child.getNextSibling();
}
} else if (name.equals("Data")) {
Node child = node.getFirstChild();
while (child != null) {
String childName = child.getNodeName();
if (childName.equals("PlanarConfiguration")) {
String pc = getAttribute(child, "value");
int planarConfiguration = -1;
if(pc.equals("PixelInterleaved")) {
planarConfiguration =
BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY;
} else if(pc.equals("PlaneInterleaved")) {
planarConfiguration =
BaselineTIFFTagSet.PLANAR_CONFIGURATION_PLANAR;
}
if(planarConfiguration != -1) {
tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_PLANAR_CONFIGURATION);
f = new TIFFField(tag, planarConfiguration);
rootIFD.addTIFFField(f);
}
} else if (childName.equals("BitsPerSample")) {
String bps = getAttribute(child, "value");
char[] bitsPerSample = listToCharArray(bps);
tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
if(isPaletteColor) {
f = new TIFFField(tag, TIFFTag.TIFF_SHORT, 1,
new char[] {bitsPerSample[0]});
} else {
f = new TIFFField(tag, TIFFTag.TIFF_SHORT,
bitsPerSample.length,
bitsPerSample);
}
rootIFD.addTIFFField(f);
} else if (childName.equals("SampleMSB")) {
// Add FillOrder only if lsb-to-msb (right to left)
// for all bands, i.e., SampleMSB is zero for all
// channels.
String sMSB = getAttribute(child, "value");
int[] sampleMSB = listToIntArray(sMSB);
boolean isRightToLeft = true;
for(int i = 0; i < sampleMSB.length; i++) {
if(sampleMSB[i] != 0) {
isRightToLeft = false;
break;
}
}
int fillOrder = isRightToLeft ?
BaselineTIFFTagSet.FILL_ORDER_RIGHT_TO_LEFT :
BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT;
tag =
rootIFD.getTag(BaselineTIFFTagSet.TAG_FILL_ORDER);
f = new TIFFField(tag, fillOrder);
rootIFD.addTIFFField(f);
}
child = child.getNextSibling();
}
} else if (name.equals("Dimension")) {
float pixelAspectRatio = -1.0f;
boolean gotPixelAspectRatio = false;
float horizontalPixelSize = -1.0f;
boolean gotHorizontalPixelSize = false;
float verticalPixelSize = -1.0f;
boolean gotVerticalPixelSize = false;
boolean sizeIsAbsolute = false;
float horizontalPosition = -1.0f;
boolean gotHorizontalPosition = false;
float verticalPosition = -1.0f;
boolean gotVerticalPosition = false;
Node child = node.getFirstChild();
while (child != null) {
String childName = child.getNodeName();
if (childName.equals("PixelAspectRatio")) {
String par = getAttribute(child, "value");
pixelAspectRatio = Float.parseFloat(par);
gotPixelAspectRatio = true;
} else if (childName.equals("ImageOrientation")) {
String orientation = getAttribute(child, "value");
for (int i = 0; i < orientationNames.length; i++) {
if (orientation.equals(orientationNames[i])) {
char[] oData = new char[1];
oData[0] = (char)i;
f = new TIFFField(
rootIFD.getTag(BaselineTIFFTagSet.TAG_ORIENTATION),
TIFFTag.TIFF_SHORT,
1,
oData);
rootIFD.addTIFFField(f);
break;
}
}
} else if (childName.equals("HorizontalPixelSize")) {
String hps = getAttribute(child, "value");
horizontalPixelSize = Float.parseFloat(hps);
gotHorizontalPixelSize = true;
} else if (childName.equals("VerticalPixelSize")) {
String vps = getAttribute(child, "value");
verticalPixelSize = Float.parseFloat(vps);
gotVerticalPixelSize = true;
} else if (childName.equals("HorizontalPosition")) {
String hp = getAttribute(child, "value");
horizontalPosition = Float.parseFloat(hp);
gotHorizontalPosition = true;
} else if (childName.equals("VerticalPosition")) {
String vp = getAttribute(child, "value");
verticalPosition = Float.parseFloat(vp);
gotVerticalPosition = true;
}
child = child.getNextSibling();
}
sizeIsAbsolute = gotHorizontalPixelSize ||
gotVerticalPixelSize;
// Fill in pixel size data from aspect ratio
if (gotPixelAspectRatio) {
if (gotHorizontalPixelSize && !gotVerticalPixelSize) {
verticalPixelSize =
horizontalPixelSize/pixelAspectRatio;
gotVerticalPixelSize = true;
} else if (gotVerticalPixelSize &&
!gotHorizontalPixelSize) {
horizontalPixelSize =
verticalPixelSize*pixelAspectRatio;
gotHorizontalPixelSize = true;
} else if (!gotHorizontalPixelSize &&
!gotVerticalPixelSize) {
horizontalPixelSize = pixelAspectRatio;
verticalPixelSize = 1.0f;
gotHorizontalPixelSize = true;
gotVerticalPixelSize = true;
}
}
// Compute pixels/centimeter
if (gotHorizontalPixelSize) {
float xResolution =
(sizeIsAbsolute ? 10.0f : 1.0f)/horizontalPixelSize;
long[][] hData = new long[1][2];
hData[0] = new long[2];
hData[0][0] = (long)(xResolution*10000.0f);
hData[0][1] = (long)10000;
f = new TIFFField(
rootIFD.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION),
TIFFTag.TIFF_RATIONAL,
1,
hData);
rootIFD.addTIFFField(f);
}
if (gotVerticalPixelSize) {
float yResolution =
(sizeIsAbsolute ? 10.0f : 1.0f)/verticalPixelSize;
long[][] vData = new long[1][2];
vData[0] = new long[2];
vData[0][0] = (long)(yResolution*10000.0f);
vData[0][1] = (long)10000;
f = new TIFFField(
rootIFD.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION),
TIFFTag.TIFF_RATIONAL,
1,
vData);
rootIFD.addTIFFField(f);
}
// Emit ResolutionUnit tag
char[] res = new char[1];
res[0] = (char)(sizeIsAbsolute ?
BaselineTIFFTagSet.RESOLUTION_UNIT_CENTIMETER :
BaselineTIFFTagSet.RESOLUTION_UNIT_NONE);
f = new TIFFField(
rootIFD.getTag(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT),
TIFFTag.TIFF_SHORT,
1,
res);
rootIFD.addTIFFField(f);
// Position
if(sizeIsAbsolute) {
if(gotHorizontalPosition) {
// Convert from millimeters to centimeters via
// numerator multiplier = denominator/10.
long[][] hData = new long[1][2];
hData[0][0] = (long)(horizontalPosition*10000.0f);
hData[0][1] = (long)100000;
f = new TIFFField(
rootIFD.getTag(BaselineTIFFTagSet.TAG_X_POSITION),
TIFFTag.TIFF_RATIONAL,
1,
hData);
rootIFD.addTIFFField(f);
}
if(gotVerticalPosition) {
// Convert from millimeters to centimeters via
// numerator multiplier = denominator/10.
long[][] vData = new long[1][2];
vData[0][0] = (long)(verticalPosition*10000.0f);
vData[0][1] = (long)100000;
f = new TIFFField(
rootIFD.getTag(BaselineTIFFTagSet.TAG_Y_POSITION),
TIFFTag.TIFF_RATIONAL,
1,
vData);
rootIFD.addTIFFField(f);
}
}
} else if (name.equals("Document")) {
Node child = node.getFirstChild();
while (child != null) {
String childName = child.getNodeName();
if (childName.equals("SubimageInterpretation")) {
String si = getAttribute(child, "value");
int newSubFileType = -1;
if(si.equals("TransparencyMask")) {
newSubFileType =
BaselineTIFFTagSet.NEW_SUBFILE_TYPE_TRANSPARENCY;
} else if(si.equals("ReducedResolution")) {
newSubFileType =
BaselineTIFFTagSet.NEW_SUBFILE_TYPE_REDUCED_RESOLUTION;
} else if(si.equals("SinglePage")) {
newSubFileType =
BaselineTIFFTagSet.NEW_SUBFILE_TYPE_SINGLE_PAGE;
}
if(newSubFileType != -1) {
tag =
rootIFD.getTag(BaselineTIFFTagSet.TAG_NEW_SUBFILE_TYPE);
f = new TIFFField(tag, newSubFileType);
rootIFD.addTIFFField(f);
}
}
if (childName.equals("ImageCreationTime")) {
String year = getAttribute(child, "year");
String month = getAttribute(child, "month");
String day = getAttribute(child, "day");
String hour = getAttribute(child, "hour");
String minute = getAttribute(child, "minute");
String second = getAttribute(child, "second");
StringBuffer sb = new StringBuffer();
sb.append(year);
sb.append(":");
if(month.length() == 1) {
sb.append("0");
}
sb.append(month);
sb.append(":");
if(day.length() == 1) {
sb.append("0");
}
sb.append(day);
sb.append(" ");
if(hour.length() == 1) {
sb.append("0");
}
sb.append(hour);
sb.append(":");
if(minute.length() == 1) {
sb.append("0");
}
sb.append(minute);
sb.append(":");
if(second.length() == 1) {
sb.append("0");
}
sb.append(second);
String[] dt = new String[1];
dt[0] = sb.toString();
f = new TIFFField(
rootIFD.getTag(BaselineTIFFTagSet.TAG_DATE_TIME),
TIFFTag.TIFF_ASCII,
1,
dt);
rootIFD.addTIFFField(f);
}
child = child.getNextSibling();
}
} else if (name.equals("Text")) {
Node child = node.getFirstChild();
String theAuthor = null;
String theDescription = null;
String theTitle = null;
while (child != null) {
String childName = child.getNodeName();
if(childName.equals("TextEntry")) {
int tagNumber = -1;
NamedNodeMap childAttrs = child.getAttributes();
Node keywordNode = childAttrs.getNamedItem("keyword");
if(keywordNode != null) {
String keyword = keywordNode.getNodeValue();
String value = getAttribute(child, "value");
if(!keyword.equals("") && !value.equals("")) {
if(keyword.equalsIgnoreCase("DocumentName")) {
tagNumber =
BaselineTIFFTagSet.TAG_DOCUMENT_NAME;
} else if(keyword.equalsIgnoreCase("ImageDescription")) {
tagNumber =
BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION;
} else if(keyword.equalsIgnoreCase("Make")) {
tagNumber =
BaselineTIFFTagSet.TAG_MAKE;
} else if(keyword.equalsIgnoreCase("Model")) {
tagNumber =
BaselineTIFFTagSet.TAG_MODEL;
} else if(keyword.equalsIgnoreCase("PageName")) {
tagNumber =
BaselineTIFFTagSet.TAG_PAGE_NAME;
} else if(keyword.equalsIgnoreCase("Software")) {
tagNumber =
BaselineTIFFTagSet.TAG_SOFTWARE;
} else if(keyword.equalsIgnoreCase("Artist")) {
tagNumber =
BaselineTIFFTagSet.TAG_ARTIST;
} else if(keyword.equalsIgnoreCase("HostComputer")) {
tagNumber =
BaselineTIFFTagSet.TAG_HOST_COMPUTER;
} else if(keyword.equalsIgnoreCase("InkNames")) {
tagNumber =
BaselineTIFFTagSet.TAG_INK_NAMES;
} else if(keyword.equalsIgnoreCase("Copyright")) {
tagNumber =
BaselineTIFFTagSet.TAG_COPYRIGHT;
} else if(keyword.equalsIgnoreCase("author")) {
theAuthor = value;
} else if(keyword.equalsIgnoreCase("description")) {
theDescription = value;
} else if(keyword.equalsIgnoreCase("title")) {
theTitle = value;
}
if(tagNumber != -1) {
f = new TIFFField(rootIFD.getTag(tagNumber),
TIFFTag.TIFF_ASCII,
1,
new String[] {value});
rootIFD.addTIFFField(f);
}
}
}
}
child = child.getNextSibling();
} // child != null
if(theAuthor != null &&
getTIFFField(BaselineTIFFTagSet.TAG_ARTIST) == null) {
f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_ARTIST),
TIFFTag.TIFF_ASCII,
1,
new String[] {theAuthor});
rootIFD.addTIFFField(f);
}
if(theDescription != null &&
getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION) == null) {
f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION),
TIFFTag.TIFF_ASCII,
1,
new String[] {theDescription});
rootIFD.addTIFFField(f);
}
if(theTitle != null &&
getTIFFField(BaselineTIFFTagSet.TAG_DOCUMENT_NAME) == null) {
f = new TIFFField(rootIFD.getTag(BaselineTIFFTagSet.TAG_DOCUMENT_NAME),
TIFFTag.TIFF_ASCII,
1,
new String[] {theTitle});
rootIFD.addTIFFField(f);
}
} else if (name.equals("Transparency")) {
Node child = node.getFirstChild();
while (child != null) {
String childName = child.getNodeName();
if (childName.equals("Alpha")) {
String alpha = getAttribute(child, "value");
f = null;
if (alpha.equals("premultiplied")) {
f = new TIFFField(
rootIFD.getTag(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES),
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA);
} else if (alpha.equals("nonpremultiplied")) {
f = new TIFFField(
rootIFD.getTag(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES),
BaselineTIFFTagSet.EXTRA_SAMPLES_UNASSOCIATED_ALPHA);
}
if (f != null) {
rootIFD.addTIFFField(f);
}
}
child = child.getNextSibling();
}
}
node = node.getNextSibling();
}
// Set SampleFormat.
if(sampleFormat != null) {
// Derive the value.
int sf = -1;
if(sampleFormat.equals("SignedIntegral")) {
sf = BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER;
} else if(sampleFormat.equals("UnsignedIntegral")) {
sf = BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER;
} else if(sampleFormat.equals("Real")) {
sf = BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT;
} else if(sampleFormat.equals("Index")) {
sf = BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER;
}
if(sf != -1) {
// Derive the count.
int count = 1;
// Try SamplesPerPixel first.
f = getTIFFField(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL);
if(f != null) {
count = f.getAsInt(0);
} else {
// Try BitsPerSample.
f = getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
if(f != null) {
count = f.getCount();
}
}
char[] sampleFormatArray = new char[count];
Arrays.fill(sampleFormatArray, (char)sf);
// Add SampleFormat.
tag = rootIFD.getTag(BaselineTIFFTagSet.TAG_SAMPLE_FORMAT);
f = new TIFFField(tag, TIFFTag.TIFF_SHORT,
sampleFormatArray.length, sampleFormatArray);
rootIFD.addTIFFField(f);
}
}
}