1 21 22 package org.armedbear.j; 23 24 import java.awt.Color ; 25 import java.awt.Cursor ; 26 import java.awt.Image ; 27 import java.awt.MediaTracker ; 28 29 public class ImageBuffer extends Buffer implements Constants 30 { 31 private static Color backgrounds[]; 32 33 static { 34 backgrounds = new Color [3]; 35 backgrounds[0] = new Color (153, 153, 153); 36 backgrounds[1] = Color.black; 37 backgrounds[2] = Color.white; 38 } 39 40 private int backgroundIndex; 41 private Image currentImage; 42 private Image originalImage; 43 private int originalWidth; 44 private int originalHeight; 45 private int currentWidth; 46 private int currentHeight; 47 private ImageLoader loader; 48 49 private ImageBuffer(File file, File cache, String listing) 50 { 51 super(); 52 mode = Editor.getModeList().getMode(IMAGE_MODE); 53 setFile(file); 54 supportsUndo = false; 55 readOnly = true; 56 autosaveEnabled = false; 57 type = TYPE_IMAGE; 58 setCache(cache); 59 setListing(listing); 60 setInitialized(true); 61 } 62 63 public static ImageBuffer createImageBuffer(File file, File cache, String listing) 64 { 65 File toBeLoaded = cache != null ? cache : file; 68 ImageLoader loader = new ImageLoader(toBeLoaded); 69 Image img = loader.loadImage(); 70 if (img != null) { 71 ImageBuffer ib = new ImageBuffer(file, cache, listing); 73 ib.loader = loader; 74 ib.currentImage = ib.originalImage = img; 75 ib.currentWidth = ib.originalWidth = img.getWidth(null); 76 ib.currentHeight = ib.originalHeight = img.getHeight(null); 77 ib.setLastModified(toBeLoaded.lastModified()); 78 ib.setLoaded(true); 79 return ib; 80 } else 81 return null; 82 } 83 84 public final Position getInitialDotPos() 85 { 86 return null; 87 } 88 89 public final boolean needsParsing() 90 { 91 return false; 92 } 93 94 public final Image getImage() 95 { 96 return currentImage; 97 } 98 99 public final int getDisplayHeight() 100 { 101 if (getModeId() == IMAGE_MODE) 102 return currentImage.getHeight(null) + Display.getImageBorderHeight() * 2; 103 else 104 return super.getDisplayHeight(); 105 } 106 107 public final int getDisplayWidth() 108 { 109 if (getModeId() == IMAGE_MODE) 110 return currentImage.getWidth(null) + Display.getImageBorderWidth() * 2; 111 else 112 return super.getDisplayWidth(); 113 } 114 115 public int load() 116 { 117 if (!isLoaded()) { 118 Debug.assertTrue(loader == null); 119 final File toBeLoaded = getCache() != null ? getCache() : getFile(); 120 loader = new ImageLoader(toBeLoaded); 121 Image img = loader.loadImage(); 122 if (img != null) { 123 currentImage = originalImage = img; 124 currentWidth = originalWidth = img.getWidth(null); 125 currentHeight = originalHeight = img.getHeight(null); 126 } else 127 MessageDialog.showMessageDialog("Error loading image", "Error"); 128 setLastModified(toBeLoaded.lastModified()); 129 setLoaded(true); 130 } 131 return LOAD_COMPLETED; 132 } 133 134 public void reload() 135 { 136 switch (getModeId()) { 137 case BINARY_MODE: 138 if (loader != null) { 139 loader.dispose(); 140 loader = null; 141 } 142 currentImage = null; 143 originalImage = null; 144 super.reload(); 145 return; 146 case IMAGE_MODE: 147 if (getFile().isLocal()) 148 reloadLocal(); 149 else 150 reloadRemote(); 151 return; 152 default: 153 Debug.bug(); 154 } 155 } 156 157 private void reloadLocal() 158 { 159 empty(); 160 if (loader != null) { 161 loader.dispose(); 162 loader = null; 163 } 164 currentImage = null; 165 originalImage = null; 166 load(); 167 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 168 Editor ed = it.nextEditor(); 169 if (ed.getBuffer() == ImageBuffer.this) { 170 ed.getDisplay().repaint(); 171 ed.updateDisplay(); 172 } 173 } 174 } 175 176 private void reloadRemote() 177 { 178 final File file = getFile(); 179 LoadProcess p = null; 180 if (file instanceof FtpFile) { 181 FtpSession session = FtpSession.getSession((FtpFile)file); 182 p = new FtpLoadProcess(this, (FtpFile)file, session); 183 } else if (file instanceof HttpFile) { 184 p = new HttpLoadProcess(this, (HttpFile)file); 185 } else { 186 Debug.bug(); 187 return; 188 } 189 final LoadProcess loadProcess = p; 190 Runnable successRunnable = new Runnable () { 191 public void run() 192 { 193 final File cache = getCache(); 194 if (cache != null && cache.isFile()) 195 cache.delete(); 196 setCache(loadProcess.getCache()); 197 reloadLocal(); 198 setBusy(false); 199 } 200 }; 201 ErrorRunnable errorRunnable = new ErrorRunnable("Reload failed"); 202 loadProcess.setProgressNotifier(new StatusBarProgressNotifier(this)); 203 loadProcess.setSuccessRunnable(successRunnable); 204 loadProcess.setErrorRunnable(errorRunnable); 205 loadProcess.start(); 206 } 207 208 public final Color getBackgroundColor() 209 { 210 return getBackground(backgroundIndex); 211 } 212 213 public static final Color getDefaultBackgroundColor() 214 { 215 return getBackground(0); 216 } 217 218 public final int getImageWidth() 219 { 220 return originalWidth; 221 } 222 223 public final int getImageHeight() 224 { 225 return originalHeight; 226 } 227 228 public final void cycleBackground() 229 { 230 if (++backgroundIndex >= getBackgroundCount()) 231 backgroundIndex = 0; 232 } 233 234 private static final int getBackgroundCount() 235 { 236 return backgrounds.length; 237 } 238 239 private static Color getBackground(int index) 240 { 241 if (index >= 0 && index < backgrounds.length) 242 return backgrounds[index]; 243 else 244 return backgrounds[0]; 245 } 246 247 public void zoomIn() 248 { 249 int w = currentWidth * 2; 250 int h = currentHeight * 2; 251 if (w > 0 && h > 0) 252 resize(w, h); 253 } 254 255 public void zoomOut() 256 { 257 int w = currentWidth / 2; 258 int h = currentHeight / 2; 259 if (w > 0 && h > 0) 260 resize(w, h); 261 } 262 263 public void fit() 264 { 265 if (originalWidth == 0 || originalHeight == 0) 266 return; 267 Editor editor = Editor.currentEditor(); 268 Display display = editor.getDisplay(); 269 int displayWidth = display.getWidth() - Display.getImageBorderWidth() * 2; 270 int displayHeight = display.getHeight() - Display.getImageBorderHeight() * 2; 271 float factor = (float) displayWidth / (float) originalWidth; 272 if (factor * originalHeight > displayHeight) 273 factor = (float) displayHeight / (float) originalHeight; 274 int w = (int) (originalWidth * factor); 275 int h = (int) (originalHeight * factor); 276 resize(w, h); 277 } 278 279 public void restore() 280 { 281 resize(originalWidth, originalHeight); 282 } 283 284 private void resize(int w, int h) 285 { 286 Editor editor = Editor.currentEditor(); 287 editor.setWaitCursor(); 288 Image img = null; 289 MediaTracker mt = null; 290 291 try 292 { 293 long pixels = w * h; 294 if (pixels > originalWidth * originalHeight && pixels > 2592000) { 295 editor.status("Too many pixels!"); 297 return; 298 } 299 long bytesRequired = pixels * 4; Runtime runtime = Runtime.getRuntime(); 301 long bytesFree = runtime.freeMemory(); 302 if (bytesRequired > bytesFree) { 303 runtime.gc(); 304 bytesFree = runtime.freeMemory(); 305 if (bytesRequired > bytesFree) { 306 editor.status("Not enough memory"); 307 return; 308 } 309 } 310 img = originalImage.getScaledInstance(w, h, Image.SCALE_DEFAULT); 311 mt = new MediaTracker (editor); 312 mt.addImage(img , 0); 313 mt.waitForID(0); 314 } 315 catch (Exception e) { 316 Log.error(e); 317 } 318 finally { 319 editor.setDefaultCursor(); 320 } 321 322 if (mt == null || mt.isErrorAny()) 323 img = null; 324 325 if (img != null) { 326 if (currentImage != originalImage) 327 currentImage.flush(); 328 currentImage = img; 329 currentWidth = img.getWidth(null); 330 currentHeight = img.getHeight(null); 331 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 332 Editor ed = it.nextEditor(); 333 if (ed.getBuffer() == this) { 334 ed.getDisplay().repaint(); 335 status(ed); 336 } 337 } 338 } 339 } 340 341 public boolean reactivate() 342 { 343 final File file = getFile(); 344 if (file == null || file.isRemote() || !file.isFile()) 345 return false; 346 if (isLoaded() && file.lastModified() != getLastModified()) { 347 reload(); 348 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 349 Editor ed = it.nextEditor(); 350 if (ed.getBuffer() == this) { 351 ed.getDisplay().repaint(); 352 status(ed); 353 } 354 } 355 return true; 356 } 357 return false; 358 } 359 360 private void status(Editor editor) 361 { 362 int percent = 363 (int) ((float) currentWidth * 100 / (float) originalWidth + 0.5); 364 editor.status(String.valueOf(percent) + '%'); 365 } 366 367 public void dispose() 368 { 369 if (loader != null) 370 loader.dispose(); 371 super.dispose(); 372 } 373 374 public Cursor getDefaultCursor() 375 { 376 return Cursor.getDefaultCursor(); 377 } 378 379 public Cursor getDefaultCursor(Position pos) 380 { 381 return Cursor.getDefaultCursor(); 382 } 383 384 public void saveView(Editor editor) 385 { 386 } 388 389 public String getStatusText(Editor editor) 390 { 391 FastStringBuffer sb = new FastStringBuffer(String.valueOf(getImageWidth())); 392 sb.append('x'); 393 sb.append(String.valueOf(getImageHeight())); 394 sb.append(" pixels"); 395 return sb.toString(); 396 } 397 } 398 | Popular Tags |