1    import java.io.*;
2    import java.awt.*;
3    import java.awt.image.*;
4    import javax.swing.*;
5    import java.util.*;
6    import java.util.zip.*;
7    import java.lang.ref.*;
8    
9    public class ImageFile implements Serializable {
10   
11     private static final long serialVersionUID = Version.getSUID();
12   
13     public static String cookprefix = "morphed";
14   
15     public static WeakHashMap files = new WeakHashMap();
16   //  public static WeakHashMap images = new WeakHashMap();
17   
18     transient SoftReference image = null;
19     File source = null;
20     File base = null;
21     File zip = null;
22   
23     public static File newbase = null;
24   
25     public static boolean newread;
26     public static boolean newwrite;
27   
28     public static int cancelcnt = 0;
29     public static int maxcancels = 3;
30   
31     public static ImageFile getImageFile(File source, File base) {
32       ImageFile ifile = new ImageFile();
33       ifile.source = source;
34       ifile.base = base;
35   
36       if (ifile.source==null) {
37         JFileChooser choose = Persist.current.getFileChooser();
38         choose.setFileFilter(new FileTypes(FileTypes.IMAGE));
39         choose.setDialogTitle("Image file");
40         if (JFileChooser.CANCEL_OPTION==choose.showDialog(null,"OK")) return(null);
41         ifile.source = choose.getSelectedFile();
42       }
43   
44       try {
45         ifile.source = ifile.source.getCanonicalFile();
46       } catch (java.io.IOException ex) {}
47   
48       return(ifile.canonical());
49     }
50   
51     private ImageFile() {}
52   
53   //  public ImageFile source) {
54   //    this.source = source;
55   //    makeCanonical();
56   //  }
57   /*
58     public void makeCanonical() {
59       if (source!=null) {
60         WeakReference cref = (WeakReference)files.get(source);
61         File csource = (cref==null ?
62           	      null : 
63           	      (File) cref.get());
64         if (csource!=null)
65           source = csource;
66         else
67           files.put(source,new WeakReference(source));
68       }
69     }
70   */
71   
72     public static void flushImages() {
73       for (Iterator it= files.values().iterator(); it.hasNext();) {
74         WeakReference ref = (WeakReference)it.next();
75         if (ref!=null) {
76           ImageFile ifile = (ImageFile)ref.get();
77           if (ifile!=null)
78             ifile.image = null;
79         }
80       }
81     }
82   
83     private Object readResolve()    throws java.io.IOException,java.io.ObjectStreamException
84     {
85       return(canonical());
86     }
87   
88     public ImageFile canonical() {
89       WeakReference cref = (WeakReference)files.get(source);
90   
91       ImageFile canonical = null;
92       if (cref!=null) canonical = (ImageFile)cref.get();
93       if (canonical!=null) return(canonical);
94   
95       files.put(source,new WeakReference(this));
96       return(this);
97     }
98   
99     public File getFile() {return(source);}
100  
101    public static void zipSave(ZipOutputStream zout, Carto carto, File backsource) {
102  //    for (Iterator it= carto.segmentlist.iterator(); it.hasNext();)
103  //      ((Segment)it.next()).isource.zipSave(zout,backsource);
104    }
105  
106    public static void fileSave(Carto carto) {
107      if (carto.zipfile==null) return;
108  
109      HashSet flist = new HashSet();
110      for (Iterator it= carto.segmentlist.iterator(); it.hasNext();)
111        flist.add(((Segment)it.next()).isource.source);
112  
113  //    for (Iterator it= flist.iterator(); it.hasNext();) {
114  //      File ifile
115    }
116  
117    public static File deltaold = null;
118    public static File deltanew = null;
119  
120    public void changename(File newsource) {
121      if (newsource.getName().equals(source.getName())) {
122        deltaold = source.getParentFile();
123        deltanew = newsource.getParentFile();
124      }
125  //    else {
126  //      deltaold = null;
127  //      deltanew = null;
128  //    }
129      files.remove(source);
130      source = newsource;
131      files.put(newsource,new WeakReference(this));
132    }
133  
134    public boolean check(File filebase,ZipFile filezip) {
135      if (!source.exists()) {
136        // Try the same substitution made last time.
137        if (deltaold!=null && source.getParentFile().equals(deltaold)) {
138          File newsource = new File(deltanew,source.getName());
139          if (newsource.exists()) {
140            changename(newsource);
141            return(true);
142          }
143        }        
144        if (filebase!=null) {
145          File newsource = new File(filebase,source.getName());
146           if (newsource.exists()) {
147            changename(newsource);
148            return(true);
149          }
150       }
151    
152       // Couldn't find the new file on our own.
153       // Time to ask.
154        while (cancelcnt<maxcancels) {
155          JFileChooser choose = Persist.current.getFileChooser();
156          choose.setFileFilter(new FileTypes(FileTypes.IMAGE));
157          choose.setDialogTitle("Image file "+source+" not found, replace with...");
158          if (JFileChooser.CANCEL_OPTION==choose.showDialog(null,"Replace "+source)) {
159            cancelcnt++;
160            return(false);
161          }
162          cancelcnt=0;
163          File newsource = choose.getSelectedFile();
164          try {
165            newsource = newsource.getCanonicalFile();
166          } catch (java.io.IOException e){}
167  
168          if (newsource.exists()) {
169            changename(newsource);
170            break;
171          }
172        }
173      }
174      Persist.current.clearChooser();
175      Persist.save();
176  
177      return(true);
178    }
179  
180    public Image getImage() {
181      if (CartoFrame.topframe.file!=null &&
182          !check(CartoFrame.topframe.file.getParentFile(),null)) return(null);
183  
184      Image res = null;
185  
186      if (image!=null) {
187        res = (Image)image.get();
188        if (res!=null) return(res);
189      }
190    
191      try {
192        res = Toolkit.getDefaultToolkit().createImage(source.getPath());
193      }
194      catch (Exception e) {
195        ErrorLog.exception(e,"Could not read image file: "+source);
196        return(null);
197      }
198  
199      if (res!=null)
200        image = new SoftReference(res);
201  
202      return(res);
203    }
204  
205    public File getCookedPath() {
206      String namestr = source.getName();
207  
208      if (!namestr.endsWith(".png")) {
209        int dot = namestr.lastIndexOf('.');
210        if (dot>=0) namestr = namestr.substring(0,dot);
211        namestr = namestr+".png";
212      }
213  
214      return(new File(source.getParent()+"/"+cookprefix+namestr));
215    }
216  
217    public Image getCooked() {
218      File cookfile = getCookedPath();
219      if (!cookfile.exists()) return(null);
220  //    System.out.println("geting cooked from "+cookfile);
221      try {
222          return(Toolkit.getDefaultToolkit().getImage(cookfile.getPath()));
223      }
224      catch (Exception e) {
225        ErrorLog.exception(e,"Could not read morphed file: "+cookfile);
226      }
227      return(null);
228      
229    }
230  
231    public void saveCooked(BufferedImage cooked) throws CookKillException {
232      File cookfile = getCookedPath();
233  //    System.out.println("saving cooked as "+cookfile);
234      try {
235        FileOutputStream out = new FileOutputStream(cookfile);
236        
237        PngEncoder encode = new PngEncoder(cooked.getWidth(null),cooked.getHeight(null),out);
238        encode.start();
239  
240        encode.addSlice(cooked,null,null);
241        
242        encode.finish();
243      } catch (IOException e) {
244        ErrorLog.exception(e,"Trouble writing morphed file: "+cookfile);
245      }
246    }
247  }
248