ArrayList 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");
ArrayList IHDRs = filterChunks(chunks, IHDR);
if (IHDRs.size() != 1)
throw new ImageReadException("PNG contains more than one Header");
PNGChunkIHDR pngChunkIHDR = (PNGChunkIHDR) IHDRs.get(0);
ArrayList 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);
// -----
ArrayList 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;
ArrayList tRNSs = filterChunks(chunks, tRNS);
if (tRNSs.size() > 0)
{
PNGChunk pngChunktRNS = (PNGChunk) tRNSs.get(0);
transparencyFilter = getTransparencyFilter(pngChunkIHDR.colorType,
pngChunktRNS);
}
ICC_Profile icc_profile = null;
GammaCorrection gammaCorrection = null;
{
ArrayList sRGBs = filterChunks(chunks, sRGB);
ArrayList gAMAs = filterChunks(chunks, gAMA);
ArrayList 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)