001    // License: GPL. See LICENSE file for details.
002    
003    package org.openstreetmap.josm.gui.layer.geoimage;
004    
005    import java.awt.Graphics2D;
006    import java.awt.Image;
007    import java.awt.MediaTracker;
008    import java.awt.Rectangle;
009    import java.awt.Toolkit;
010    import java.awt.image.BufferedImage;
011    import java.util.ArrayList;
012    import java.util.List;
013    
014    import org.openstreetmap.josm.Main;
015    import org.openstreetmap.josm.io.CacheFiles;
016    
017    public class ThumbsLoader implements Runnable {
018        public static final int maxSize = 120;
019        public static final int minSize = 22;
020        volatile boolean stop = false;
021        List<ImageEntry> data;
022        GeoImageLayer layer;
023        MediaTracker tracker;
024        CacheFiles cache;
025        boolean cacheOff = Main.pref.getBoolean("geoimage.noThumbnailCache", false);
026    
027        public ThumbsLoader(GeoImageLayer layer) {
028            this.layer = layer;
029            this.data = new ArrayList<ImageEntry>(layer.data);
030            if (!cacheOff) {
031                cache = new CacheFiles("geoimage-thumbnails", false);
032                cache.setExpire(CacheFiles.EXPIRE_NEVER, false);
033                cache.setMaxSize(120, false);
034            }
035        }
036    
037        public void run() {
038            System.err.println("Load Thumbnails");
039            tracker = new MediaTracker(Main.map.mapView);
040            for (int i = 0; i < data.size(); i++) {
041                if (stop) return;
042    
043                System.err.print("fetching image "+i);
044    
045                data.get(i).thumbnail = loadThumb(data.get(i));
046    
047                if (Main.isDisplayingMapView()) {
048                    layer.updateOffscreenBuffer = true;
049                    Main.map.mapView.repaint();
050                }
051            }
052            layer.updateOffscreenBuffer = true;
053            Main.map.mapView.repaint();
054            (new Thread() {             // clean up the garbage - shouldn't hurt
055                @Override
056                public void run() {
057                    try {
058                        Thread.sleep(200);
059                    }
060                    catch (InterruptedException ie) {}
061                    System.gc();
062                }
063            }).start();
064    
065        }
066    
067        private BufferedImage loadThumb(ImageEntry entry) {
068            final String cacheIdent = entry.getFile().toString()+":"+maxSize;
069    
070            if (!cacheOff) {
071                BufferedImage cached = cache.getImg(cacheIdent);
072                if(cached != null) {
073                    System.err.println(" from cache");
074                    return cached;
075                }
076            }
077    
078            Image img = Toolkit.getDefaultToolkit().createImage(entry.getFile().getPath());
079            tracker.addImage(img, 0);
080            try {
081                tracker.waitForID(0);
082            } catch (InterruptedException e) {
083                System.err.println(" InterruptedException");
084                return null;
085            }
086            if (tracker.isErrorID(1) || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
087                System.err.println(" Invalid image");
088                return null;
089            }
090            Rectangle targetSize = ImageDisplay.calculateDrawImageRectangle(
091                    new Rectangle(0, 0, img.getWidth(null), img.getHeight(null)),
092                    new Rectangle(0, 0, maxSize, maxSize));
093            BufferedImage scaledBI = new BufferedImage(targetSize.width, targetSize.height, BufferedImage.TYPE_INT_RGB);
094            Graphics2D g = scaledBI.createGraphics();
095            while (!g.drawImage(img, 0, 0, targetSize.width, targetSize.height, null))
096            {
097                try {
098                    Thread.sleep(10);
099                } catch(InterruptedException ie) {}
100            }
101            g.dispose();
102            tracker.removeImage(img);
103    
104            if (scaledBI.getWidth() <= 0 || scaledBI.getHeight() <= 0) {
105                System.err.println(" Invalid image");
106                return null;
107            }
108    
109            if (!cacheOff) {
110                cache.saveImg(cacheIdent, scaledBI);
111            }
112    
113            System.err.println("");
114            return scaledBI;
115        }
116    
117    }