-
Bug
-
Resolution: Fixed
-
P4
-
7
-
b92
-
x86
-
windows_7
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8143513 | emb-9 | Sergey Bylokhov | P4 | Resolved | Fixed | team |
FULL PRODUCT VERSION :
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [versão 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
I`m using the default BMP plugin (com.sun.imageio.plugins.bmp.BMPImageReader) to read BMP images, and I need to get the resolution information from it`s the metadata (com.sun.imageio.plugins.bmp.BMPMetadata).
When I navigate the Standard Metadata Tree (javax_imageio_1.0 / Dimension / VerticalPhysicalPixelSpacing -or- javax_imageio_1.0 / Dimension / HorizontalPhysicalPixelSpacing), the pixel sizes are always set to zero.
I have checked the source code, and I found the bug in the method BMPMetadata.getStandardDimensionNode():
subNode = new IIOMetadataNode("HorizontalPhysicalPixelSpacing");
subNode.setAttribute("value", "" + (1 / xPixelsPerMeter * 1000));
node.appendChild(subNode);
subNode = new IIOMetadataNode("VerticalPhysicalPixelSpacing");
subNode.setAttribute("value", "" + (1 / yPixelsPerMeter * 1000));
node.appendChild(subNode);
Essentially, the integer division (1 / xPixelsPerMeter) truncates the result, returning zero. It must be perform the calculation with floating point.
I suggest rewriting it as:
subNode.setAttribute("value", "" + (1000.0 / xPixelsPerMeter));
subNode.setAttribute("value", "" + (1000.0 / yPixelsPerMeter));
Apparently this bug has been around un-noticed for a long time, all versions of the BMPMetadata source found have the same bug.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just use ImageIO to read the Standard Metadata from a BMP file.
A sample is provided to display the Standard Metadata Tree from a file called "image.bmp"
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
For a 500-DPI image, I expected to get the following pixel dimension nodes:
<....>
<HorizontalPhysicalPixelSpacing value="0.05"/>
<VerticalPhysicalPixelSpacing value="0.05"/>
<....>
ACTUAL -
<....>
<HorizontalPhysicalPixelSpacing value="0"/>
<VerticalPhysicalPixelSpacing value="0"/>
<....>
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class BMPMetadataTest {
public static void printTree(Node doc, int ident) {
for (int i=0; i<ident; i++)
System.out.print("\t");
System.out.print("<"+doc.getNodeName());
NamedNodeMap cl = doc.getAttributes();
for (int i = 0; i < cl.getLength(); i++) {
Node node = cl.item(i);
System.out.print(" " + node.getNodeName() + "=\"" + node.getNodeValue() + "\"");
}
NodeList nl = doc.getChildNodes();
if (nl.getLength()==0) {
System.out.println("/>");
} else {
System.out.println(">");
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
printTree(node, ident+1);
}
for (int i=0; i<ident; i++)
System.out.print("\t");
System.out.println("</"+doc.getNodeName()+">");
}
}
public static void ShowBMPMetadata(InputStream inputStream) throws Exception {
ImageInputStream imageInput = ImageIO.createImageInputStream(inputStream);
for (Iterator<ImageReader> it = ImageIO.getImageReaders(imageInput); it.hasNext(); ) {
ImageReader reader = it.next();
reader.setInput(imageInput);
IIOMetadata metadata = reader.getImageMetadata(0);
Node rootNode = metadata.getAsTree("javax_imageio_1.0");
printTree(rootNode, 0);
}
}
public static void main(String[] args) throws Exception {
ShowBMPMetadata(new FileInputStream("image.bmp"));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have provided a fix in the description, but it is difficult to "workaround" it - Specially considering I didn't plan to write BMP-specific code
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [versão 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
I`m using the default BMP plugin (com.sun.imageio.plugins.bmp.BMPImageReader) to read BMP images, and I need to get the resolution information from it`s the metadata (com.sun.imageio.plugins.bmp.BMPMetadata).
When I navigate the Standard Metadata Tree (javax_imageio_1.0 / Dimension / VerticalPhysicalPixelSpacing -or- javax_imageio_1.0 / Dimension / HorizontalPhysicalPixelSpacing), the pixel sizes are always set to zero.
I have checked the source code, and I found the bug in the method BMPMetadata.getStandardDimensionNode():
subNode = new IIOMetadataNode("HorizontalPhysicalPixelSpacing");
subNode.setAttribute("value", "" + (1 / xPixelsPerMeter * 1000));
node.appendChild(subNode);
subNode = new IIOMetadataNode("VerticalPhysicalPixelSpacing");
subNode.setAttribute("value", "" + (1 / yPixelsPerMeter * 1000));
node.appendChild(subNode);
Essentially, the integer division (1 / xPixelsPerMeter) truncates the result, returning zero. It must be perform the calculation with floating point.
I suggest rewriting it as:
subNode.setAttribute("value", "" + (1000.0 / xPixelsPerMeter));
subNode.setAttribute("value", "" + (1000.0 / yPixelsPerMeter));
Apparently this bug has been around un-noticed for a long time, all versions of the BMPMetadata source found have the same bug.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just use ImageIO to read the Standard Metadata from a BMP file.
A sample is provided to display the Standard Metadata Tree from a file called "image.bmp"
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
For a 500-DPI image, I expected to get the following pixel dimension nodes:
<....>
<HorizontalPhysicalPixelSpacing value="0.05"/>
<VerticalPhysicalPixelSpacing value="0.05"/>
<....>
ACTUAL -
<....>
<HorizontalPhysicalPixelSpacing value="0"/>
<VerticalPhysicalPixelSpacing value="0"/>
<....>
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class BMPMetadataTest {
public static void printTree(Node doc, int ident) {
for (int i=0; i<ident; i++)
System.out.print("\t");
System.out.print("<"+doc.getNodeName());
NamedNodeMap cl = doc.getAttributes();
for (int i = 0; i < cl.getLength(); i++) {
Node node = cl.item(i);
System.out.print(" " + node.getNodeName() + "=\"" + node.getNodeValue() + "\"");
}
NodeList nl = doc.getChildNodes();
if (nl.getLength()==0) {
System.out.println("/>");
} else {
System.out.println(">");
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
printTree(node, ident+1);
}
for (int i=0; i<ident; i++)
System.out.print("\t");
System.out.println("</"+doc.getNodeName()+">");
}
}
public static void ShowBMPMetadata(InputStream inputStream) throws Exception {
ImageInputStream imageInput = ImageIO.createImageInputStream(inputStream);
for (Iterator<ImageReader> it = ImageIO.getImageReaders(imageInput); it.hasNext(); ) {
ImageReader reader = it.next();
reader.setInput(imageInput);
IIOMetadata metadata = reader.getImageMetadata(0);
Node rootNode = metadata.getAsTree("javax_imageio_1.0");
printTree(rootNode, 0);
}
}
public static void main(String[] args) throws Exception {
ShowBMPMetadata(new FileInputStream("image.bmp"));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have provided a fix in the description, but it is difficult to "workaround" it - Specially considering I didn't plan to write BMP-specific code
- backported by
-
JDK-8143513 BMPMetadata returns invalid PhysicalPixelSpacing
-
- Resolved
-