/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: PreloaderImageIO.java 1452610 2013-03-05 01:00:35Z lbernardo $ */
package org.apache.xmlgraphics.image.loader.impl.imageio;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.Source;
import org.apache.xmlgraphics.image.loader.ImageContext;
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.AbstractImagePreloader;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
Image preloader for images supported by ImageIO.
Note: The implementation relies on the presence of a working ImageIO implementation which
provides accurate image metadata. This is particularly important for PNG image because the
PNG loader relies on that.
/**
* Image preloader for images supported by ImageIO.
* <p>
* Note: The implementation relies on the presence of a working ImageIO implementation which
* provides accurate image metadata. This is particularly important for PNG image because the
* PNG loader relies on that.
*/
public class PreloaderImageIO extends AbstractImagePreloader {
{@inheritDoc}
Throws:
/** {@inheritDoc}
* @throws ImageException */
public ImageInfo preloadImage(String uri, Source src, ImageContext context)
throws IOException, ImageException {
if (!ImageUtil.hasImageInputStream(src)) {
return null;
}
ImageInputStream in = ImageUtil.needImageInputStream(src);
Iterator iter = ImageIO.getImageReaders(in);
if (!iter.hasNext()) {
return null;
}
IOException firstIOException = null;
IIOMetadata iiometa = null;
ImageSize size = null;
String mime = null;
while (iter.hasNext()) {
in.mark();
ImageReader reader = (ImageReader)iter.next();
try {
reader.setInput(ImageUtil.ignoreFlushing(in), true, false);
final int imageIndex = 0;
iiometa = reader.getImageMetadata(imageIndex);
size = new ImageSize();
size.setSizeInPixels(reader.getWidth(imageIndex), reader.getHeight(imageIndex));
mime = reader.getOriginatingProvider().getMIMETypes()[0];
break;
} catch (IOException ioe) {
//remember the first exception, ignore all others and continue
if (firstIOException == null) {
firstIOException = ioe;
}
} finally {
reader.dispose();
in.reset();
}
}
if (iiometa == null) {
if (firstIOException == null) {
throw new ImageException("Could not extract image metadata");
} else {
throw new ImageException("I/O error while extracting image metadata"
+ (firstIOException.getMessage() != null
? ": " + firstIOException.getMessage()
: ""),
firstIOException);
}
}
//Resolution (first a default, then try to read the metadata)
size.setResolution(context.getSourceResolution());
ImageIOUtil.extractResolution(iiometa, size);
if (size.getWidthPx() <= 0 || size.getHeightPx() <= 0) {
//Watch out for a special case: a TGA image was erroneously identified
//as a WBMP image by a Sun ImageIO codec.
return null;
}
if (size.getWidthMpt() == 0) {
size.calcSizeFromPixels();
}
ImageInfo info = new ImageInfo(uri, mime);
info.getCustomObjects().put(ImageIOUtil.IMAGEIO_METADATA, iiometa);
info.setSize(size);
return info;
}
{@inheritDoc} /** {@inheritDoc} */
public int getPriority() {
//Lower priority than default to give the specialized preloaders a chance.
return 2 * DEFAULT_PRIORITY;
}
}