// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.data.cache;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* Cache Entry that has methods to get the BufferedImage, that will be cached along in memory
* but will be not serialized when saved to the disk (to avoid duplication of data)
*
* @author Wiktor Niesiobędzki
*/
public class BufferedImageCacheEntry extends CacheEntry {
private static final long serialVersionUID = 1L; //version
// transient to avoid serialization, volatile to avoid synchronization of whole getImage() method
private transient volatile BufferedImage img;
// we need to have separate control variable, to know, if we already tried to load the image, as img might be null
// after we loaded image, as for example, when image file is malformed (eg. HTML file)
private transient volatile boolean imageLoaded;
/**
*
* @param content byte array containing image
*/
public BufferedImageCacheEntry(byte[] content) {
super(content);
}
/**
* Returns BufferedImage from for the content. Subsequent calls will return the same instance,
* to reduce overhead of ImageIO
*
* @return BufferedImage of cache entry content
* @throws IOException if an error occurs during reading.
*/
public BufferedImage getImage() throws IOException {
if (imageLoaded)
return img;
synchronized (this) {
if (imageLoaded)
return img;
byte[] content = getContent();
if (content.length > 0) {
img = ImageIO.read(new ByteArrayInputStream(content));
imageLoaded = true;
}
}
return img;
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
/*
* This method below will be needed, if Apache Commons JCS (or any other caching system), will update
* disk representation of object from memory, once it is put into the cache (for example - at closing the cache)
*
* For now it is not the case, as we use DiskUsagePattern.UPDATE, which on JCS shutdown doesn't write again memory
* contents to file, so the fact, that we've cleared never gets saved to the disk
*
* This method is commented out, as it will convert all cache entries to PNG files regardless of what was returned.
* It might cause recompression/change of format which may result in decreased quality of imagery
*/
/* synchronized (this) {
if (content == null && img != null) {
ByteArrayOutputStream restoredData = new ByteArrayOutputStream();
ImageIO.write(img, "png", restoredData);
content = restoredData.toByteArray();
}
out.writeObject(this);
}
*/
synchronized (this) {
if (content == null && img != null) {
throw new AssertionError("Trying to serialize (save to disk?) an BufferedImageCacheEntry " +
"that was converted to BufferedImage and no raw data is present anymore");
}
out.writeObject(this);
if (img != null) {
content = null;
}
}
}
}