in src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java [411:546]
public ImageInfo getImageInfo(final ByteSource byteSource, final PngImagingParameters params) throws ImagingException, IOException {
final List<PngChunk> chunks = readChunks(byteSource, new ChunkType[] { ChunkType.IHDR, ChunkType.pHYs, ChunkType.sCAL, ChunkType.tEXt, ChunkType.zTXt,
ChunkType.tRNS, ChunkType.PLTE, ChunkType.iTXt, }, false);
if (chunks.isEmpty()) {
throw new ImagingException("PNG: no chunks");
}
final List<PngChunk> IHDRs = filterChunks(chunks, ChunkType.IHDR);
if (IHDRs.size() != 1) {
throw new ImagingException("PNG contains more than one Header");
}
final PngChunkIhdr pngChunkIHDR = (PngChunkIhdr) IHDRs.get(0);
boolean transparent = false;
final List<PngChunk> tRNSs = filterChunks(chunks, ChunkType.tRNS);
if (!tRNSs.isEmpty()) {
transparent = true;
} else {
// CE - Fix Alpha.
transparent = pngChunkIHDR.getPngColorType().hasAlpha();
// END FIX
}
PngChunkPhys pngChunkpHYs = null;
final List<PngChunk> pHYss = filterChunks(chunks, ChunkType.pHYs);
if (pHYss.size() > 1) {
throw new ImagingException("PNG contains more than one pHYs: " + pHYss.size());
}
if (pHYss.size() == 1) {
pngChunkpHYs = (PngChunkPhys) pHYss.get(0);
}
PhysicalScale physicalScale = PhysicalScale.UNDEFINED;
final List<PngChunk> sCALs = filterChunks(chunks, ChunkType.sCAL);
if (sCALs.size() > 1) {
throw new ImagingException("PNG contains more than one sCAL:" + sCALs.size());
}
if (sCALs.size() == 1) {
final PngChunkScal pngChunkScal = (PngChunkScal) sCALs.get(0);
if (pngChunkScal.getUnitSpecifier() == 1) {
physicalScale = PhysicalScale.createFromMeters(pngChunkScal.getUnitsPerPixelXAxis(), pngChunkScal.getUnitsPerPixelYAxis());
} else {
physicalScale = PhysicalScale.createFromRadians(pngChunkScal.getUnitsPerPixelXAxis(), pngChunkScal.getUnitsPerPixelYAxis());
}
}
final List<PngChunk> tEXts = filterChunks(chunks, ChunkType.tEXt);
final List<PngChunk> zTXts = filterChunks(chunks, ChunkType.zTXt);
final List<PngChunk> iTXts = filterChunks(chunks, ChunkType.iTXt);
final int chunkCount = tEXts.size() + zTXts.size() + iTXts.size();
final List<String> comments = Allocator.arrayList(chunkCount);
final List<AbstractPngText> textChunks = Allocator.arrayList(chunkCount);
for (final PngChunk tEXt : tEXts) {
final PngChunkText pngChunktEXt = (PngChunkText) tEXt;
comments.add(pngChunktEXt.getKeyword() + ": " + pngChunktEXt.getText());
textChunks.add(pngChunktEXt.getContents());
}
for (final PngChunk zTXt : zTXts) {
final PngChunkZtxt pngChunkzTXt = (PngChunkZtxt) zTXt;
comments.add(pngChunkzTXt.getKeyword() + ": " + pngChunkzTXt.getText());
textChunks.add(pngChunkzTXt.getContents());
}
for (final PngChunk iTXt : iTXts) {
final PngChunkItxt pngChunkiTXt = (PngChunkItxt) iTXt;
comments.add(pngChunkiTXt.getKeyword() + ": " + pngChunkiTXt.getText());
textChunks.add(pngChunkiTXt.getContents());
}
final int bitsPerPixel = pngChunkIHDR.getBitDepth() * pngChunkIHDR.getPngColorType().getSamplesPerPixel();
final ImageFormat format = ImageFormats.PNG;
final String formatName = "PNG Portable Network Graphics";
final int height = pngChunkIHDR.getHeight();
final String mimeType = "image/png";
final int numberOfImages = 1;
final int width = pngChunkIHDR.getWidth();
final boolean progressive = pngChunkIHDR.getInterlaceMethod().isProgressive();
int physicalHeightDpi = -1;
float physicalHeightInch = -1;
int physicalWidthDpi = -1;
float physicalWidthInch = -1;
// if (pngChunkpHYs != null)
// {
// System.out.println("\t" + "pngChunkpHYs.UnitSpecifier: " +
// pngChunkpHYs.UnitSpecifier );
// System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitYAxis: " +
// pngChunkpHYs.PixelsPerUnitYAxis );
// System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitXAxis: " +
// pngChunkpHYs.PixelsPerUnitXAxis );
// }
if (pngChunkpHYs != null && pngChunkpHYs.getUnitSpecifier() == 1) { // meters
final double metersPerInch = 0.0254;
physicalWidthDpi = (int) Math.round(pngChunkpHYs.getPixelsPerUnitXAxis() * metersPerInch);
physicalWidthInch = (float) (width / (pngChunkpHYs.getPixelsPerUnitXAxis() * metersPerInch));
physicalHeightDpi = (int) Math.round(pngChunkpHYs.getPixelsPerUnitYAxis() * metersPerInch);
physicalHeightInch = (float) (height / (pngChunkpHYs.getPixelsPerUnitYAxis() * metersPerInch));
}
boolean usesPalette = false;
final List<PngChunk> PLTEs = filterChunks(chunks, ChunkType.PLTE);
if (!PLTEs.isEmpty()) {
usesPalette = true;
}
final ImageInfo.ColorType colorType;
switch (pngChunkIHDR.getPngColorType()) {
case GREYSCALE:
case GREYSCALE_WITH_ALPHA:
colorType = ImageInfo.ColorType.GRAYSCALE;
break;
case TRUE_COLOR:
case INDEXED_COLOR:
case TRUE_COLOR_WITH_ALPHA:
colorType = ImageInfo.ColorType.RGB;
break;
default:
throw new ImagingException("Png: Unknown ColorType: " + pngChunkIHDR.getPngColorType());
}
final String formatDetails = "Png";
final ImageInfo.CompressionAlgorithm compressionAlgorithm = ImageInfo.CompressionAlgorithm.PNG_FILTER;
return new PngImageInfo(formatDetails, bitsPerPixel, comments, format, formatName, height, mimeType, numberOfImages, physicalHeightDpi,
physicalHeightInch, physicalWidthDpi, physicalWidthInch, width, progressive, transparent, usesPalette, colorType, compressionAlgorithm,
textChunks, physicalScale);
}