package net.sharenav.midlet.util;
/*
* ShareNav - Copyright (c) 2012 sk750 at users dot sourceforge dot net
* See Copying
*/
import javax.microedition.lcdui.Image;
import java.io.IOException;
import java.lang.Integer;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Hashtable;
import net.sharenav.gps.location.GetCompass;
import net.sharenav.util.Logger;
import de.enough.polish.util.Locale;
class ImgId {
short width;
short height;
public ImgId(int width, int height) {
this.width = (short) width;
this.height = (short) height;
}
public boolean equals(Object o){
if (o == null || !(o instanceof ImgId) || o.getClass() != this.getClass()) {
return false;
}
ImgId other = (ImgId) o;
if (other.width != this.width || other.height != this.height) {
return false;
}
return true;
}
public int hashCode() {
return this.width + this.height;
}
public String toString() {
return "(" + this.width + "x" + this.height + ")";
}
}
class ImgIdFile extends ImgId {
String fileName;
public ImgIdFile(String fileName, int width, int height) {
super(width, height);
this.fileName = fileName;
}
public boolean equals(Object o){
if (super.equals(o)) {
ImgIdFile other = (ImgIdFile) o;
if (this.fileName.equalsIgnoreCase(other.fileName)) {
return true;
}
}
return false;
}
public int hashCode() {
return super.hashCode() + fileName.hashCode();
}
public String toString() {
return this.fileName + super.toString();
}
}
class ImgIdOneColor extends ImgId {
int color;
public ImgIdOneColor(int color, int width, int height) {
super(width, height);
this.color = color;
}
public boolean equals(Object o){
if (super.equals(o)) {
ImgIdOneColor other = (ImgIdOneColor) o;
if (this.color == other.color) {
return true;
}
}
return false;
}
public int hashCode() {
return super.hashCode() + this.color;
}
public String toString() {
return "oneColor" + super.toString();
}
}
class ImgIdBaseImage extends ImgId {
Image baseImage;
public ImgIdBaseImage(Image baseImage, int width, int height) {
super(width, height);
this.baseImage = baseImage;
}
public boolean equals(Object o){
if (super.equals(o)) {
ImgIdBaseImage other = (ImgIdBaseImage) o;
if (other.baseImage == this.baseImage) {
return true;
}
}
return false;
}
public int hashCode() {
return super.hashCode() + this.baseImage.hashCode();
}
public String toString() {
return baseImage + super.toString();
}
}
class CacheEntry {
Image img;
long lastUsedTime;
public CacheEntry(Image img) {
this.img = img;
this.lastUsedTime = System.currentTimeMillis();
}
}
public class ImageCache {
private final static Logger logger = Logger.getInstance(ImageCache.class,Logger.DEBUG);
private static Hashtable imageCache = new Hashtable();
private static long lastCleanup = 0;
/** returns an Image object of the given filename in its original width and height, either by loading it or taking it from the cache */
public static Image getImageFromFile(String fileName) {
return getImageFromFile(fileName, 0, 0);
}
/** returns an Image object of the given filename in the given width and height, either by loading it or taking it from the cache */
public static Image getImageFromFile(String fileName, int width, int height) {
ImgIdFile id = new ImgIdFile(fileName, width, height);
CacheEntry cacheEntry = (CacheEntry) imageCache.get(id);
if (cacheEntry != null) {
return getCachedImage(cacheEntry);
}
Image img;
// file system image
try {
img = Image.createImage(fileName);
// System.out.println("Caching " + id.toString());
} catch (IOException ioe) {
logger.error("Cannot load " + fileName);
return null;
}
if (width != 0) {
img = ImageTools.scaleImage(img, width, height);
}
return cacheImage(img, id);
}
/**
* @param img
* @param id
*/
public static Image cacheImage(Image img, ImgId id) {
if (img != null) {
// System.out.println("Caching " + id.toString());
imageCache.put(id, new CacheEntry(img));
}
return img;
}
/** returns an Image object of the given base image in the given width and height, either by resizing it or taking it from the cache */
public static Image getScaledImage(Image baseImage, int width, int height) {
ImgIdBaseImage id = new ImgIdBaseImage(baseImage, width, height);
CacheEntry cacheEntry = (CacheEntry) imageCache.get(id);
if (cacheEntry != null) {
return getCachedImage(cacheEntry);
}
Image img = null;
if (width != 0) {
img = ImageTools.scaleImage(baseImage, width, height);
}
return cacheImage(img, id);
}
/** returns an Image object of the given one color in the given width and height, either by creating it or taking it from the cache */
public static Image getOneColorImage(int color, int width, int height) {
cleanup();
ImgIdOneColor id = new ImgIdOneColor(color, width, height);
CacheEntry cacheEntry = (CacheEntry) imageCache.get(id);
if (cacheEntry != null) {
return getCachedImage(cacheEntry);
}
Image img;
int rawSize = width * height;
int[] rawOutput = new int[rawSize];
for (int outOffset = 0; outOffset < rawSize;) {
rawOutput[outOffset++]= color;
}
try {
img = Image.createRGBImage(rawOutput, width, height, true);
} catch (Exception e) {
logger.exception("Cannot create one color image", e);
return null;
}
return cacheImage(img, id);
}
public static Image getCachedImage(CacheEntry cacheEntry) {
cacheEntry.lastUsedTime = System.currentTimeMillis();
//System.out.println("Loaded from cache " + id.toString());
return cacheEntry.img;
}
public static void cleanup() {
long now = System.currentTimeMillis();
if (Math.abs(now - lastCleanup) > 30000) {
cleanup(30000);
}
}
/** uncache all cached images that have not been used longer than the given time */
public static void cleanup(int minUnusedMillis) {
Vector remove = new Vector();
long now = System.currentTimeMillis();
for (Enumeration e = imageCache.keys() ; e.hasMoreElements() ;) {
ImgId id = (ImgId) e.nextElement();
CacheEntry cachedImage = (CacheEntry) imageCache.get(id);
if (Math.abs(now - cachedImage.lastUsedTime) > minUnusedMillis) {
remove.addElement(id);
// System.out.println("Uncaching " + id.toString());
}
}
while (!remove.isEmpty()) {
imageCache.remove(remove.firstElement());
remove.removeElementAt(0);
}
lastCleanup = now;
}
public static void testImageCache() {
Image img;
System.out.println("Testing ImageCache");
img = getImageFromFile("/bus.png", 20, 20);
img = getImageFromFile("/church.png", 20, 20);
img = getImageFromFile("/bus.png", 20, 20);
cleanup(0);
img = getImageFromFile("/bus.png", 20, 20);
img = getImageFromFile("/church.png", 20, 20);
img = getImageFromFile("/church.png", 20, 20);
}
}