public Image loadImage(ImageInfo info, Map hints, ImageSessionContext session)
throws ImageException, IOException {
RenderedImage imageData = null;
IIOException firstException = null;
IIOMetadata iiometa = (IIOMetadata)info.getCustomObjects().get(
ImageIOUtil.IMAGEIO_METADATA);
boolean ignoreMetadata = (iiometa != null);
boolean providerIgnoresICC = false;
Source src = session.needSource(info.getOriginalURI());
ImageInputStream imgStream = ImageUtil.needImageInputStream(src);
try {
Iterator iter = ImageIO.getImageReaders(imgStream);
while (iter.hasNext()) {
ImageReader reader = (ImageReader)iter.next();
try {
imgStream.mark();
ImageReadParam param = reader.getDefaultReadParam();
reader.setInput(imgStream, false, ignoreMetadata);
final int pageIndex = ImageUtil.needPageIndexFromURI(info.getOriginalURI());
try {
if (ImageFlavor.BUFFERED_IMAGE.equals(this.targetFlavor)) {
imageData = reader.read(pageIndex, param);
} else {
imageData = reader.read(pageIndex, param);
//imageData = reader.readAsRenderedImage(pageIndex, param);
//TODO Reenable the above when proper listeners are implemented
//to react to late pixel population (so the stream can be closed
//properly).
}
if (iiometa == null) {
iiometa = reader.getImageMetadata(pageIndex);
}
providerIgnoresICC = checkProviderIgnoresICC(reader
.getOriginatingProvider());
break; //Quit early, we have the image
} catch (IndexOutOfBoundsException indexe) {
throw new ImageException("Page does not exist. Invalid image index: "
+ pageIndex);
} catch (IllegalArgumentException iae) {
//Some codecs like com.sun.imageio.plugins.wbmp.WBMPImageReader throw
//IllegalArgumentExceptions when they have trouble parsing the image.
throw new ImageException("Error loading image using ImageIO codec", iae);
} catch (IIOException iioe) {
if (firstException == null) {
firstException = iioe;
} else {
log.debug("non-first error loading image: " + iioe.getMessage());
}
}
try {
//Try fallback for CMYK images
BufferedImage bi = getFallbackBufferedImage(reader, pageIndex, param);
imageData = bi;
firstException = null; //Clear exception after successful fallback attempt
break;
} catch (IIOException iioe) {
//ignore
}
imgStream.reset();
} finally {
reader.dispose();
}
}
} finally {
ImageUtil.closeQuietly(src);
//TODO Some codecs may do late reading.
}
if (firstException != null) {
throw new ImageException("Error while loading image: "
+ firstException.getMessage(), firstException);
}
if (imageData == null) {
throw new ImageException("No ImageIO ImageReader found .");
}
ColorModel cm = imageData.getColorModel();
Color transparentColor = null;
if (cm instanceof IndexColorModel) {
//transparent color will be extracted later from the image
} else {
if (providerIgnoresICC && cm instanceof ComponentColorModel) {
// Apply ICC Profile to Image by creating a new image with a new
// color model.
ICC_Profile iccProf = tryToExctractICCProfile(iiometa);
if (iccProf != null) {
ColorModel cm2 = new ComponentColorModel(
new ICC_ColorSpace(iccProf), cm.hasAlpha(), cm
.isAlphaPremultiplied(), cm
.getTransparency(), cm.getTransferType());
WritableRaster wr = Raster.createWritableRaster(imageData
.getSampleModel(), null);
imageData.copyData(wr);
try {
BufferedImage bi = new BufferedImage(cm2, wr, cm2
.isAlphaPremultiplied(), null);
imageData = bi;
cm = cm2;
} catch (IllegalArgumentException iae) {
log.warn("Image " + info.getOriginalURI()
+ " has an incompatible color profile."
+ " The color profile will be ignored."
+ "\nColor model of loaded bitmap: " + cm
+ "\nColor model of color profile: " + cm2);
}
}
}
// ImageIOUtil.dumpMetadataToSystemOut(iiometa);
// Retrieve the transparent color from the metadata
if (iiometa != null && iiometa.isStandardMetadataFormatSupported()) {
Element metanode = (Element)iiometa.getAsTree(
IIOMetadataFormatImpl.standardMetadataFormatName);
Element dim = ImageIOUtil.getChild(metanode, "Transparency");
if (dim != null) {
Element child;
child = ImageIOUtil.getChild(dim, "TransparentColor");