Changeset 13220 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2017-12-18T00:46:58+01:00 (7 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
r13206 r13220 80 80 import org.openstreetmap.josm.io.GpxReader; 81 81 import org.openstreetmap.josm.spi.preferences.Config; 82 import org.openstreetmap.josm.tools.ExifReader;83 82 import org.openstreetmap.josm.tools.GBC; 84 83 import org.openstreetmap.josm.tools.ImageProvider; … … 459 458 imgList.getSelectionModel().addListSelectionListener(evt -> { 460 459 int index = imgList.getSelectedIndex(); 461 Integer orientation = ExifReader.readOrientation(yLayer.data.get(index).getFile()); 462 imgDisp.setImage(yLayer.data.get(index).getFile(), orientation); 460 imgDisp.setImage(yLayer.data.get(index)); 463 461 Date date = yLayer.data.get(index).getExifTime(); 464 462 if (date != null) { … … 483 481 if (fc == null) 484 482 return; 485 File sel = fc.getSelectedFile(); 486 487 Integer orientation = ExifReader.readOrientation(sel); 488 imgDisp.setImage(sel, orientation); 489 490 Date date = ExifReader.readTime(sel); 483 ImageEntry entry = new ImageEntry(fc.getSelectedFile()); 484 entry.extractExif(); 485 imgDisp.setImage(entry); 486 487 Date date = entry.getExifTime(); 491 488 if (date != null) { 492 489 lbExifTime.setText(DateUtils.getDateTimeFormat(DateFormat.SHORT, DateFormat.MEDIUM).format(date)); -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageDisplay.java
r13191 r13220 46 46 47 47 /** The file that is currently displayed */ 48 private File file;48 private ImageEntry entry; 49 49 50 50 /** The image currently displayed */ … … 215 215 private class LoadImageRunnable implements Runnable, ImageObserver { 216 216 217 private final ImageEntry entry; 217 218 private final File file; 218 private final int orientation; 219 private int width; 220 private int height; 221 222 LoadImageRunnable(File file, Integer orientation) { 223 this.file = file; 224 this.orientation = orientation == null ? -1 : orientation; 219 220 LoadImageRunnable(ImageEntry entry) { 221 this.entry = entry; 222 this.file = entry.getFile(); 225 223 } 226 224 … … 229 227 if (((infoflags & ImageObserver.WIDTH) == ImageObserver.WIDTH) && 230 228 ((infoflags & ImageObserver.HEIGHT) == ImageObserver.HEIGHT)) { 231 this.width = width;232 this.height = height;233 synchronized (this) {234 this.notify();229 synchronized (entry) { 230 entry.setWidth(width); 231 entry.setHeight(height); 232 entry.notifyAll(); 235 233 return false; 236 234 } 237 235 } 238 236 return true; 237 } 238 239 private boolean updateImageEntry(Image img) { 240 if (!(entry.getWidth() > 0 && entry.getHeight() > 0)) { 241 synchronized (entry) { 242 img.getWidth(this); 243 img.getHeight(this); 244 245 long now = System.currentTimeMillis(); 246 while (!(entry.getWidth() > 0 && entry.getHeight() > 0)) { 247 try { 248 entry.wait(1000); 249 if (this.entry != ImageDisplay.this.entry) 250 return false; 251 if (System.currentTimeMillis() - now > 10000) 252 synchronized (ImageDisplay.this) { 253 errorLoading = true; 254 ImageDisplay.this.repaint(); 255 return false; 256 } 257 } catch (InterruptedException e) { 258 Logging.trace(e); 259 Logging.warn("InterruptedException in {0} while getting properties of image {1}", 260 getClass().getSimpleName(), file.getPath()); 261 Thread.currentThread().interrupt(); 262 } 263 } 264 } 265 } 266 return true; 267 } 268 269 private boolean mayFitMemory(long amountWanted) { 270 return amountWanted < ( 271 Runtime.getRuntime().maxMemory() - 272 Runtime.getRuntime().totalMemory() + 273 Runtime.getRuntime().freeMemory()); 239 274 } 240 275 … … 242 277 public void run() { 243 278 Image img = Toolkit.getDefaultToolkit().createImage(file.getPath()); 244 245 synchronized (this) { 246 width = -1; 247 img.getWidth(this); 248 img.getHeight(this); 249 250 while (width < 0) { 251 try { 252 this.wait(); 253 if (width < 0) { 254 errorLoading = true; 255 return; 256 } 257 } catch (InterruptedException e) { 258 e.printStackTrace(); 259 } 260 } 261 } 262 263 long allocatedMem = Runtime.getRuntime().totalMemory() - 264 Runtime.getRuntime().freeMemory(); 265 long mem = Runtime.getRuntime().maxMemory()-allocatedMem; 266 267 if (mem > ((long) width*height*4)*2) { 279 if (!updateImageEntry(img)) 280 return; 281 282 int width = entry.getWidth(); 283 int height = entry.getHeight(); 284 285 if (mayFitMemory(((long) width)*height*4*2)) { 268 286 Logging.info("Loading {0} using default toolkit", file.getPath()); 269 287 tracker.addImage(img, 1); … … 271 289 // Wait for the end of loading 272 290 while (!tracker.checkID(1, true)) { 273 if (this. file != ImageDisplay.this.file) {291 if (this.entry != ImageDisplay.this.entry) { 274 292 // The file has changed 275 293 tracker.removeImage(img); … … 280 298 } catch (InterruptedException e) { 281 299 Logging.trace(e); 282 Logging.warn("InterruptedException in "+getClass().getSimpleName()+283 " while loading image "+file.getPath());300 Logging.warn("InterruptedException in {0} while loading image {1}", 301 getClass().getSimpleName(), file.getPath()); 284 302 Thread.currentThread().interrupt(); 285 303 } 286 304 } 287 305 if (tracker.isErrorID(1)) { 306 // the tracker catches OutOfMemory conditions 288 307 img = null; 289 System.gc();290 308 } 291 309 } else { … … 293 311 } 294 312 295 if (img == null || width <= 0 || height <= 0) {296 tracker.removeImage(img);297 img = null;298 }299 300 313 synchronized (ImageDisplay.this) { 301 if (this. file != ImageDisplay.this.file) {314 if (this.entry != ImageDisplay.this.entry) { 302 315 // The file has changed 303 316 tracker.removeImage(img); … … 307 320 if (img != null) { 308 321 boolean switchedDim = false; 309 if (ExifReader.orientationNeedsCorrection( orientation)) {310 if (ExifReader.orientationSwitchesDimensions( orientation)) {322 if (ExifReader.orientationNeedsCorrection(entry.getExifOrientation())) { 323 if (ExifReader.orientationSwitchesDimensions(entry.getExifOrientation())) { 311 324 width = img.getHeight(null); 312 325 height = img.getWidth(null); … … 314 327 } 315 328 final BufferedImage rot = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 316 final AffineTransform xform = ExifReader.getRestoreOrientationTransform(orientation, 317 img.getWidth(null), img.getHeight(null)); 329 final AffineTransform xform = ExifReader.getRestoreOrientationTransform( 330 entry.getExifOrientation(), 331 img.getWidth(null), 332 img.getHeight(null)); 318 333 final Graphics2D g = rot.createGraphics(); 319 334 g.drawImage(img, xform, null); … … 326 341 visibleRect = new VisRect(0, 0, width, height); 327 342 328 Logging.info("Loaded {0} with dimensions {1}x{2} mem (prev-avail={3}m,taken={4}m) exifOrientationSwitchedDimension={5}",329 file.getPath(), width, height, mem/1024/1024,width*height*4/1024/1024, switchedDim);343 Logging.info("Loaded {0} with dimensions {1}x{2} memoryTaken={3}m exifOrientationSwitchedDimension={4}", 344 file.getPath(), width, height, width*height*4/1024/1024, switchedDim); 330 345 } 331 346 … … 361 376 362 377 private void mouseWheelMovedImpl(int x, int y, int rotation, boolean refreshMousePointInImg) { 363 File file;378 ImageEntry entry; 364 379 Image image; 365 380 VisRect visibleRect; 366 381 367 382 synchronized (ImageDisplay.this) { 368 file = ImageDisplay.this.file;383 entry = ImageDisplay.this.entry; 369 384 image = ImageDisplay.this.image; 370 385 visibleRect = ImageDisplay.this.visibleRect; … … 418 433 419 434 synchronized (ImageDisplay.this) { 420 if (ImageDisplay.this. file == file) {435 if (ImageDisplay.this.entry == entry) { 421 436 ImageDisplay.this.visibleRect = visibleRect; 422 437 } … … 447 462 public void mouseClicked(MouseEvent e) { 448 463 // Move the center to the clicked point. 449 File file;464 ImageEntry entry; 450 465 Image image; 451 466 VisRect visibleRect; 452 467 453 468 synchronized (ImageDisplay.this) { 454 file = ImageDisplay.this.file;469 entry = ImageDisplay.this.entry; 455 470 image = ImageDisplay.this.image; 456 471 visibleRect = ImageDisplay.this.visibleRect; … … 486 501 487 502 synchronized (ImageDisplay.this) { 488 if (ImageDisplay.this. file == file) {503 if (ImageDisplay.this.entry == entry) { 489 504 ImageDisplay.this.visibleRect = visibleRect; 490 505 } … … 519 534 return; 520 535 521 File file;536 ImageEntry entry; 522 537 Image image; 523 538 VisRect visibleRect; 524 539 525 540 synchronized (ImageDisplay.this) { 526 file = ImageDisplay.this.file;541 entry = ImageDisplay.this.entry; 527 542 image = ImageDisplay.this.image; 528 543 visibleRect = ImageDisplay.this.visibleRect; … … 539 554 visibleRect.checkRectPos(); 540 555 synchronized (ImageDisplay.this) { 541 if (ImageDisplay.this. file == file) {556 if (ImageDisplay.this.entry == entry) { 542 557 ImageDisplay.this.visibleRect = visibleRect; 543 558 } … … 565 580 @Override 566 581 public void mouseReleased(MouseEvent e) { 567 File file;582 ImageEntry entry; 568 583 Image image; 584 VisRect visibleRect; 569 585 570 586 synchronized (ImageDisplay.this) { 571 file = ImageDisplay.this.file;587 entry = ImageDisplay.this.entry; 572 588 image = ImageDisplay.this.image; 589 visibleRect = ImageDisplay.this.visibleRect; 573 590 } 574 591 … … 614 631 615 632 synchronized (ImageDisplay.this) { 616 if ( file == ImageDisplay.this.file) {633 if (entry == ImageDisplay.this.entry) { 617 634 if (selectedRect == null) { 618 635 ImageDisplay.this.visibleRect = visibleRect; … … 656 673 /** 657 674 * Sets a new source image to be displayed by this {@code ImageDisplay}. 658 * @param filenew source image659 * @ param orientation orientation of new source (landscape, portrait, upside-down, etc.)675 * @param entry new source image 676 * @since 13220 660 677 */ 661 public void setImage( File file, Integer orientation) {678 public void setImage(ImageEntry entry) { 662 679 synchronized (this) { 663 this. file = file;680 this.entry = entry; 664 681 image = null; 665 682 errorLoading = false; 666 683 } 667 684 repaint(); 668 if ( file!= null) {669 new Thread(new LoadImageRunnable( file, orientation), LoadImageRunnable.class.getName()).start();685 if (entry != null) { 686 new Thread(new LoadImageRunnable(entry), LoadImageRunnable.class.getName()).start(); 670 687 } 671 688 } … … 682 699 @Override 683 700 public void paintComponent(Graphics g) { 701 ImageEntry entry; 684 702 Image image; 685 File file;686 703 VisRect visibleRect; 687 704 boolean errorLoading; … … 689 706 synchronized (this) { 690 707 image = this.image; 691 file = this.file;708 entry = this.entry; 692 709 visibleRect = this.visibleRect; 693 710 errorLoading = this.errorLoading; … … 699 716 700 717 Dimension size = getSize(); 701 if ( file== null) {718 if (entry == null) { 702 719 g.setColor(Color.black); 703 720 String noImageStr = tr("No image"); … … 710 727 String loadingStr; 711 728 if (!errorLoading) { 712 loadingStr = tr("Loading {0}", file.getName());729 loadingStr = tr("Loading {0}", entry.getFile().getName()); 713 730 } else { 714 loadingStr = tr("Error on file {0}", file.getName());731 loadingStr = tr("Error on file {0}", entry.getFile().getName()); 715 732 } 716 733 Rectangle2D noImageSize = g.getFontMetrics(g.getFont()).getStringBounds(loadingStr, g); … … 742 759 r.x = visibleRect.x; 743 760 r.y = visibleRect.y; 744 System.gc();745 761 } 746 762 } else { … … 772 788 } 773 789 if (errorLoading) { 774 String loadingStr = tr("Error on file {0}", file.getName());790 String loadingStr = tr("Error on file {0}", entry.getFile().getName()); 775 791 Rectangle2D noImageSize = g.getFontMetrics(g.getFont()).getStringBounds(loadingStr, g); 776 792 g.drawString(loadingStr, … … 885 901 */ 886 902 public void zoomBestFitOrOne() { 887 File file;903 ImageEntry entry; 888 904 Image image; 889 905 VisRect visibleRect; 890 906 891 907 synchronized (this) { 892 file = this.file;908 entry = this.entry; 893 909 image = this.image; 894 910 visibleRect = this.visibleRect; … … 911 927 912 928 synchronized (this) { 913 if ( file == this.file) {929 if (this.entry == entry) { 914 930 this.visibleRect = visibleRect; 915 931 } -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java
r13060 r13220 21 21 import com.drew.metadata.exif.ExifIFD0Directory; 22 22 import com.drew.metadata.exif.GpsDirectory; 23 import com.drew.metadata.jpeg.JpegDirectory; 23 24 24 25 /** … … 53 54 private Date gpsTime; 54 55 56 private int width; 57 private int height; 58 55 59 /** 56 60 * When the correlation dialog is open, we like to show the image position … … 77 81 78 82 /** 83 * Returns width of the image this ImageEntry represents. 84 * @return width of the image this ImageEntry represents 85 * @since 13220 86 */ 87 public int getWidth() { 88 return width; 89 } 90 91 /** 92 * Returns height of the image this ImageEntry represents. 93 * @return height of the image this ImageEntry represents 94 * @since 13220 95 */ 96 public int getHeight() { 97 return height; 98 } 99 100 /** 79 101 * Returns the position value. The position value from the temporary copy 80 102 * is returned if that copy exists. … … 142 164 */ 143 165 public Integer getExifOrientation() { 144 return exifOrientation ;166 return exifOrientation != null ? exifOrientation : 1; 145 167 } 146 168 … … 228 250 new ThumbsLoader(Collections.singleton(this)).run(); 229 251 } 252 } 253 254 /** 255 * Sets the width of this ImageEntry. 256 * @param width set the width of this ImageEntry 257 * @since 13220 258 */ 259 public void setWidth(int width) { 260 this.width = width; 261 } 262 263 /** 264 * Sets the height of this ImageEntry. 265 * @param height set the height of this ImageEntry 266 * @since 13220 267 */ 268 public void setHeight(int height) { 269 this.height = height; 230 270 } 231 271 … … 457 497 } 458 498 499 final Directory dir = metadata.getFirstDirectoryOfType(JpegDirectory.class); 459 500 final Directory dirExif = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); 460 501 final GpsDirectory dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class); … … 464 505 int orientation = dirExif.getInt(ExifIFD0Directory.TAG_ORIENTATION); 465 506 setExifOrientation(orientation); 507 } 508 } catch (MetadataException ex) { 509 Logging.debug(ex); 510 } 511 512 try { 513 if (dir != null) { 514 // there are cases where these do not match width and height stored in dirExif 515 int width = dir.getInt(JpegDirectory.TAG_IMAGE_WIDTH); 516 int height = dir.getInt(JpegDirectory.TAG_IMAGE_HEIGHT); 517 setWidth(width); 518 setHeight(height); 466 519 } 467 520 } catch (MetadataException ex) { -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java
r13130 r13220 323 323 // Set only if the image is new to preserve zoom and position if the same image is redisplayed 324 324 // (e.g. to update the OSD). 325 imgDisplay.setImage(entry .getFile(), entry.getExifOrientation());325 imgDisplay.setImage(entry); 326 326 } 327 327 setTitle(tr("Geotagged Images") + (entry.getFile() != null ? " - " + entry.getFile().getName() : "")); … … 356 356 // do not actually show the dialog again with a blank image if currently hidden (fix #10672) 357 357 setTitle(tr("Geotagged Images")); 358 imgDisplay.setImage(null , null);358 imgDisplay.setImage(null); 359 359 imgDisplay.setOsdText(""); 360 360 return; -
trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/KeyedItem.java
r11384 r13220 100 100 * A set of values that were used for this key. 101 101 */ 102 public final SortedSet<String> values = new TreeSet<>(); ;// NOSONAR102 public final SortedSet<String> values = new TreeSet<>(); // NOSONAR 103 103 private boolean hadKeys; 104 104 private boolean hadEmpty;
Note:
See TracChangeset
for help on using the changeset viewer.