Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6541476
Votes 1
Synopsis PNG imageio plugin incorrectly handles iTXt chunk
Category java:imageio
Reported Against
Release Fixed 7(b43), 6u12(b01) (Bug ID:2168950)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs
Submit Date 02-APR-2007
Description
FULL PRODUCT VERSION :
java version "1.6.0",
java version "1.5.0_04",
java version "1.4.2_05"

ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.19-1.2288.2.4.fc5,
 customer  Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
com.sun.imageio.plugins.pngPNGMetadata#mergeNativeTree incorrectly stores iTXt_compressionFlag values.   At line 1406 (iTXt_compressionFlag.add(new Boolean(compressionFlag));), values are added to the iTXt_compressionFlag ArrayList as Boolean objects.  If they are later retieved in a call to getNativeTree the objects are cast to Integer, which creates an exception.  Other references to iTXt_compressionFlag use Integer, so line 1406 should store the value as an integer.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
a new test.png file, with an iTXt cluster containing the text "<xml></xml>"
ACTUAL -
java.lang.ClassCastException, see below

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Integer
	at com.sun.imageio.plugins.png.PNGImageWriter.write_iTXt(PNGImageWriter.java:680)
	at com.sun.imageio.plugins.png.PNGImageWriter.write(PNGImageWriter.java:1120)
	at javax.imageio.ImageWriter.write(ImageWriter.java:580)
	at org.mbari.aosn.moqua.image.Test1.main(Test1.java:56)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package org.mbari.aosn.moqua.image;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.IIOImage;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormat;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageOutputStream;

import org.w3c.dom.Node;

import com.sun.imageio.plugins.png.PNGImageWriter;
import com.sun.imageio.plugins.png.PNGImageWriterSpi;

public class Test1 {

	static public void main(String args[]) {
		try {
			File file = new File("test.png");
			BufferedImage image = new BufferedImage(128, 128,
					BufferedImage.TYPE_4BYTE_ABGR_PRE);
			Graphics2D graph = image.createGraphics();
			graph.setPaintMode();
			graph.setColor(Color. customer );
			graph.fillRect(32, 32, 64, 64);
			graph.dispose();
			ImageOutputStream imageOutputStream = new FileImageOutputStream(
					file);
			ImageTypeSpecifier imageTypeSpecifier = new ImageTypeSpecifier(
					image);
			ImageWriter imageWriter = new PNGImageWriter(
					new PNGImageWriterSpi());
			imageWriter.setOutput(imageOutputStream);
			IIOMetadata metadata = imageWriter.getDefaultImageMetadata(
					imageTypeSpecifier, null);
			String formatNames[] = metadata.getMetadataFormatNames();
			for (String formatName : formatNames) {
				IIOMetadataFormat format = metadata
						.getMetadataFormat(formatName);
				Node node = metadata.getAsTree(formatName);
				if (formatName.contains("png")) {
					IIOMetadataNode iTXt = new IIOMetadataNode("iTXt");
					IIOMetadataNode iTXtEntry = new IIOMetadataNode("iTXtEntry");
					iTXtEntry.setAttribute("keyword", "XML:com. customer .xmp");
					iTXtEntry.setAttribute("compressionFlag", "false");
					iTXtEntry.setAttribute("compressionMethod", "0");
					iTXtEntry.setAttribute("languageTag", "en");
					iTXtEntry.setAttribute("translatedKeyword",
							"XML:com. customer .xmp");
					iTXtEntry.setAttribute("text", "<xml></xml>");
					iTXt.appendChild(iTXtEntry);
					node.appendChild(iTXt);
					metadata.setFromTree(formatName, node);
					break;
				}
			}
			imageWriter.write(new IIOImage(image, null, metadata));
			imageOutputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
before calling mageWriter.write(new IIOImage(image, null, metadata));
insert the following lines (which resolves this problem and a similar problem involving iTXt_compressionMethod):

			if(metadata instanceof PNGMetadata){
				List iTXt_compressionFlag = ((PNGMetadata)metadata).iTXt_compressionFlag;
				for(int i = 0; i < iTXt_compressionFlag.size(); ++i){
					Object flag = iTXt_compressionFlag.get(i);
					if(flag instanceof Boolean){
						iTXt_compressionFlag.set(i,Integer.valueOf(((Boolean)flag).booleanValue()?1:0));
					}
				}
				List iTXt_compressionMethod = ((PNGMetadata)metadata).iTXt_compressionMethod;
				for(int i = 0; i < iTXt_compressionMethod.size(); ++i){
					Object method = iTXt_compressionMethod.get(i);
					if(method instanceof String){
						try{
							iTXt_compressionMethod.set(i,Integer.valueOf((String)method));
						} catch (NumberFormatException NFE) {
							iTXt_compressionMethod.set(i,Integer.valueOf(0));
						}
					}
				}
			}
Posted Date : 2007-04-02 13:33:18.0
Work Around
N/A
Evaluation
The CR 6541476 is about problem with a writing of iTXt chunk
 but we read it incorrectly too if this chunk contains 
 non-ascii data (namely, translatedKeyword and text attributes
 may contain UTF8 data).

The main reason of reading failures is the DataInputStream.readUTF()
 function usage.  This function interprets first two bytes in the
 input stream as a string data length and seems to be designed 
 for de-serialization purposes only.

The idea of fix is to avoid usage of this function and pay attention
 to expected data encoding on writing and reading stage.

Another problem is that PNG metadata class uses collections (ArraList,
 for example) without specifying the type of stored data. It may lead
 to  problem like described in this CR. To avoid this, we can specify 
 data type for each collection.
Posted Date : 2008-10-31 13:31:14.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang