in src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java [681:856]
public BufferedImage getBufferedImage(ByteSource byteSource, Map params)
throws ImageReadException, IOException
{
boolean verbose = ParamMap.getParamBoolean(params, PARAM_KEY_VERBOSE,
false);
if (params.containsKey(PARAM_KEY_VERBOSE))
params.remove(PARAM_KEY_VERBOSE);
// if (params.size() > 0) {
// Object firstKey = params.keySet().iterator().next();
// throw new ImageWriteException("Unknown parameter: " + firstKey);
// }
List<PngChunk> chunks = readChunks(byteSource, new int[] { IHDR, PLTE, IDAT,
tRNS, iCCP, gAMA, sRGB, }, false);
if ((chunks == null) || (chunks.size() < 1))
throw new ImageReadException("PNG: no chunks");
List<PngChunk> IHDRs = filterChunks(chunks, IHDR);
if (IHDRs.size() != 1)
throw new ImageReadException("PNG contains more than one Header");
PngChunkIhdr pngChunkIHDR = (PngChunkIhdr) IHDRs.get(0);
List<PngChunk> PLTEs = filterChunks(chunks, PLTE);
if (PLTEs.size() > 1)
throw new ImageReadException("PNG contains more than one Palette");
PngChunkPlte pngChunkPLTE = null;
if (PLTEs.size() == 1)
pngChunkPLTE = (PngChunkPlte) PLTEs.get(0);
// -----
List<PngChunk> IDATs = filterChunks(chunks, IDAT);
if (IDATs.size() < 1)
throw new ImageReadException("PNG missing image data");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (int i = 0; i < IDATs.size(); i++)
{
PngChunkIdat pngChunkIDAT = (PngChunkIdat) IDATs.get(i);
byte bytes[] = pngChunkIDAT.bytes;
// System.out.println(i + ": bytes: " + bytes.length);
baos.write(bytes);
}
byte compressed[] = baos.toByteArray();
baos = null;
TransparencyFilter transparencyFilter = null;
List<PngChunk> tRNSs = filterChunks(chunks, tRNS);
if (tRNSs.size() > 0)
{
PngChunk pngChunktRNS = tRNSs.get(0);
transparencyFilter = getTransparencyFilter(pngChunkIHDR.colorType,
pngChunktRNS);
}
ICC_Profile icc_profile = null;
GammaCorrection gammaCorrection = null;
{
List<PngChunk> sRGBs = filterChunks(chunks, sRGB);
List<PngChunk> gAMAs = filterChunks(chunks, gAMA);
List<PngChunk> iCCPs = filterChunks(chunks, iCCP);
if (sRGBs.size() > 1)
throw new ImageReadException("PNG: unexpected sRGB chunk");
if (gAMAs.size() > 1)
throw new ImageReadException("PNG: unexpected gAMA chunk");
if (iCCPs.size() > 1)
throw new ImageReadException("PNG: unexpected iCCP chunk");
if (sRGBs.size() == 1)
{
// no color management neccesary.
if (debug)
System.out.println("sRGB, no color management neccesary.");
} else if (iCCPs.size() == 1)
{
if (debug)
System.out.println("iCCP.");
PngChunkIccp pngChunkiCCP = (PngChunkIccp) iCCPs.get(0);
byte bytes[] = pngChunkiCCP.UncompressedProfile;
icc_profile = ICC_Profile.getInstance(bytes);
} else if (gAMAs.size() == 1)
{
PngChunkGama pngChunkgAMA = (PngChunkGama) gAMAs.get(0);
double gamma = pngChunkgAMA.getGamma();
// charles: what is the correct target value here?
// double targetGamma = 2.2;
double targetGamma = 1.0;
double diff = Math.abs(targetGamma - gamma);
if (diff >= 0.5)
gammaCorrection = new GammaCorrection(gamma, targetGamma);
if (gammaCorrection != null)
if (pngChunkPLTE != null)
pngChunkPLTE.correct(gammaCorrection);
}
}
{
int width = pngChunkIHDR.width;
int height = pngChunkIHDR.height;
int colorType = pngChunkIHDR.colorType;
int bitDepth = pngChunkIHDR.bitDepth;
int bitsPerSample = bitDepth;
if (pngChunkIHDR.filterMethod != 0)
throw new ImageReadException("PNG: unknown FilterMethod: "
+ pngChunkIHDR.filterMethod);
int samplesPerPixel = samplesPerPixel(pngChunkIHDR.colorType);
boolean isGrayscale = isGrayscale(pngChunkIHDR.colorType);
int bitsPerPixel = bitsPerSample * samplesPerPixel;
boolean hasAlpha = colorType == COLOR_TYPE_GREYSCALE_WITH_ALPHA
|| colorType == COLOR_TYPE_TRUE_COLOR_WITH_ALPHA;
BufferedImage result;
if (isGrayscale)
result = getBufferedImageFactory(params)
.getGrayscaleBufferedImage(width, height, hasAlpha);
else
result = getBufferedImageFactory(params).getColorBufferedImage(
width, height, hasAlpha);
ByteArrayInputStream bais = new ByteArrayInputStream(compressed);
InflaterInputStream iis = new InflaterInputStream(bais);
ScanExpediter scanExpediter;
if (pngChunkIHDR.interlaceMethod == 0)
scanExpediter = new ScanExpediterSimple(width, height, iis,
result, colorType, bitDepth, bitsPerPixel,
pngChunkPLTE, gammaCorrection, transparencyFilter);
else if (pngChunkIHDR.interlaceMethod == 1)
scanExpediter = new ScanExpediterInterlaced(width, height, iis,
result, colorType, bitDepth, bitsPerPixel,
pngChunkPLTE, gammaCorrection, transparencyFilter);
else
throw new ImageReadException("Unknown InterlaceMethod: "
+ pngChunkIHDR.interlaceMethod);
scanExpediter.drive();
if (icc_profile != null)
{
Boolean is_srgb = new IccProfileParser().issRGB(icc_profile);
if (is_srgb == null || !is_srgb.booleanValue())
{
ICC_ColorSpace cs = new ICC_ColorSpace(icc_profile);
ColorModel srgbCM = ColorModel.getRGBdefault();
ColorSpace cs_sRGB = srgbCM.getColorSpace();
result = new ColorTools().convertBetweenColorSpaces(result,
cs, cs_sRGB);
}
}
return result;
}
}