package net.sf.jpluck.handlers;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import net.sf.jpluck.ClientConfiguration;
import net.sf.jpluck.jxl.ImageSettings;
import net.sf.jpluck.palm.bitmap.Bitmap;
import net.sf.jpluck.palm.bitmap.CompositeBitmap;
import net.sf.jpluck.palm.bitmap.ImageConverter;
import net.sf.jpluck.plucker.CompositeImageRecord;
import net.sf.jpluck.plucker.ImageRecord;
import net.sf.jpluck.spider.Resource;
public class ImageHandler extends ContentHandler {
public ImageHandler(net.sf.jpluck.plucker.Document pluckerDocument, net.sf.jpluck.jxl.Document jxlDocument,
Resource resource) {
super(pluckerDocument, jxlDocument, resource);
}
public void handle() throws HandlingException {
try {
Logger.getLogger("handler").info("Converting " + resource.getURI());
BufferedImage image;
if (ClientConfiguration.getDefault().isUseImageIO()) {
image = ImageIO.read(new ByteArrayInputStream(resource.getData()));
} else {
Image image2 = new ImageIcon(resource.getData()).getImage();
JLabel observer = new JLabel();
int width = image2.getWidth(observer);
int height = image2.getHeight(observer);
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setBackground(Color.WHITE);
g.clearRect(0, 0, width, height);
g.drawImage(image2, 0, 0, observer);
g.dispose();
image2.flush();
}
if (image == null) {
return;
}
if (resource.isEmbedded()) {
ImageSettings embeddedSettings = jxlDocument.getEmbeddedImageSettings();
BufferedImage embeddedImage;
if (ClientConfiguration.getDefault().isUseMultiImage()) {
embeddedImage = ImageConverter.rescale(image, embeddedSettings.getMaxWidth(),
embeddedSettings.getMaxHeight());
addCompositeImage(resource, embeddedImage, embeddedSettings, false);
} else {
embeddedImage = ImageConverter.rescale(image, embeddedSettings.getBitDepth(),
embeddedSettings.getMaxWidth(),
embeddedSettings.getMaxHeight());
Bitmap bitmap = ImageConverter.convert(embeddedImage, embeddedSettings.getBitDepth());
ImageRecord imageRecord = resource.createImageRecord(bitmap, false);
pluckerDocument.addRecord(imageRecord);
}
if (!embeddedSettings.isIncludeAlternate() ||
((image.getWidth() <= embeddedImage.getWidth()) &&
(image.getHeight() <= embeddedImage.getHeight()))) {
return;
}
}
if ((jxlDocument.isIncludeStandaloneImages())) {
// TODO: Improve heuristic for determining whether to include an alternate image.
ImageSettings standaloneSettings = jxlDocument.getStandaloneImageSettings();
if (ClientConfiguration.getDefault().isUseMultiImage()) {
BufferedImage standaloneImage = ImageConverter.rescale(image, standaloneSettings.getMaxWidth(),
standaloneSettings.getMaxHeight());
addCompositeImage(resource, standaloneImage, standaloneSettings, resource.isEmbedded());
} else {
BufferedImage standaloneImage = ImageConverter.rescale(image, standaloneSettings.getMaxWidth(),
standaloneSettings.getMaxHeight());
int width = standaloneImage.getWidth();
int height = standaloneImage.getHeight();
int targetBitDepth = standaloneSettings.getBitDepth();
int maxPossiblebitDepth = 0;
if ((maxPossiblebitDepth == 0) && (targetBitDepth >= 8)) {
if ((width * height) <= 60000) {
maxPossiblebitDepth = 8;
}
}
if ((maxPossiblebitDepth == 0) && (targetBitDepth >= 4)) {
if ((width * height) <= 120000) {
maxPossiblebitDepth = 4;
}
}
if ((maxPossiblebitDepth == 0) && (targetBitDepth >= 2)) {
if ((width * height) <= 240000) {
maxPossiblebitDepth = 2;
}
}
if ((maxPossiblebitDepth == 0) && (targetBitDepth >= 1)) {
if ((width * height) <= 480000) {
maxPossiblebitDepth = 1;
}
}
if (maxPossiblebitDepth > 0) {
Bitmap bitmap = ImageConverter.convert(standaloneImage, maxPossiblebitDepth);
ImageRecord imageRecord = resource.createImageRecord(bitmap, resource.isEmbedded());
pluckerDocument.addRecord(imageRecord);
}
}
}
} catch (IOException e) {
throw new HandlingException(e);
}
}
private void addCompositeImage(Resource resource, BufferedImage image, ImageSettings imageSettings,
boolean alternate) {
CompositeBitmap compositeBitmap = CompositeBitmap.create(image, imageSettings.getBitDepth());
if (compositeBitmap.getRows() == 1) {
ImageRecord imageRecord = resource.createImageRecord(compositeBitmap.getBitmapAt(0, 0), alternate);
pluckerDocument.addRecord(imageRecord);
} else {
String[] segmentURIs = new String[compositeBitmap.getRows()];
String uri = (resource.isRedirected() ? resource.getRedirectionURI() : resource.getURI());
if (alternate) {
uri += ".alternate";
}
for (int i = 0, n = compositeBitmap.getRows(); i < n; i++) {
segmentURIs[i] = uri + "-" + (i + 1);
pluckerDocument.addRecord(new ImageRecord(segmentURIs[i], compositeBitmap.getBitmapAt(i, 0)));
}
CompositeImageRecord imageRecord = resource.createCompositeImageRecord(segmentURIs, 1, alternate);
pluckerDocument.addRecord(imageRecord);
}
}
}