Changeset 10862 in josm for trunk/src/com/drew/metadata/exif
- Timestamp:
- 2016-08-20T20:58:03+02:00 (8 years ago)
- Location:
- trunk/src/com/drew/metadata/exif
- Files:
-
- 4 added
- 50 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/com/drew/metadata/exif/ExifDescriptorBase.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 30 30 31 31 import java.io.UnsupportedEncodingException; 32 import java.math.RoundingMode; 32 33 import java.text.DecimalFormat; 33 34 import java.util.HashMap; … … 51 52 @NotNull 52 53 private static final java.text.DecimalFormat SimpleDecimalFormatter = new DecimalFormat("0.#"); 53 @NotNull54 private static final java.text.DecimalFormat SimpleDecimalFormatterWithPrecision = new DecimalFormat("0.0");55 54 56 55 // Note for the potential addition of brightness presentation in eV: … … 206 205 case TAG_JPEG_PROC: 207 206 return getJpegProcDescription(); 207 case TAG_LENS_SPECIFICATION: 208 return getLensSpecificationDescription(); 208 209 default: 209 210 return super.getDescription(tagType); … … 509 510 510 511 @Nullable 512 public String getLensSpecificationDescription() 513 { 514 return getLensSpecificationDescription(TAG_LENS_SPECIFICATION); 515 } 516 517 @Nullable 511 518 public String getSharpnessDescription() 512 519 { … … 568 575 ? null 569 576 : value == 0 570 ? "Unknown"571 : SimpleDecimalFormatter.format(value) + "mm";577 ? "Unknown" 578 : getFocalLengthDescription(value); 572 579 } 573 580 … … 579 586 ? null 580 587 : value.getNumerator() == 0 581 ? "Digital zoom not used."582 : SimpleDecimalFormatter.format(value.doubleValue());588 ? "Digital zoom not used" 589 : SimpleDecimalFormatter.format(value.doubleValue()); 583 590 } 584 591 … … 711 718 return null; 712 719 double fStop = PhotographicConversions.apertureToFStop(aperture); 713 return "f/" + SimpleDecimalFormatterWithPrecision.format(fStop);720 return getFStopDescription(fStop); 714 721 } 715 722 … … 721 728 return null; 722 729 double fStop = PhotographicConversions.apertureToFStop(aperture); 723 return "f/" + SimpleDecimalFormatterWithPrecision.format(fStop);730 return getFStopDescription(fStop); 724 731 } 725 732 … … 807 814 { 808 815 Rational value = _directory.getRational(TAG_FOCAL_LENGTH); 809 if (value == null) 810 return null; 811 java.text.DecimalFormat formatter = new DecimalFormat("0.0##"); 812 return formatter.format(value.doubleValue()) + " mm"; 816 return value == null ? null : getFocalLengthDescription(value.doubleValue()); 813 817 } 814 818 … … 859 863 public String getWhiteBalanceDescription() 860 864 { 861 // '0' means unknown, '1' daylight, '2' fluorescent, '3' tungsten, '4' flash, 862 // '17' standard light A, '18' standard light B, '19' standard light C, '20' D55, 863 // '21' D65, '22' D75, '255' other. 864 // see http://web.archive.org/web/20131018091152/http://exif.org/Exif2-2.PDF page 35 865 // See http://web.archive.org/web/20131018091152/http://exif.org/Exif2-2.PDF page 35 865 866 final Integer value = _directory.getInteger(TAG_WHITE_BALANCE); 866 867 if (value == null) … … 875 876 case 10: return "Cloudy"; 876 877 case 11: return "Shade"; 877 case 12: return "Daylight Fl ourescent";878 case 13: return "Day White Fl ourescent";879 case 14: return "Cool White Fl ourescent";880 case 15: return "White Fl ourescent";881 case 16: return "Warm White Fl ourescent";878 case 12: return "Daylight Fluorescent"; 879 case 13: return "Day White Fluorescent"; 880 case 14: return "Cool White Fluorescent"; 881 case 15: return "White Fluorescent"; 882 case 16: return "Warm White Fluorescent"; 882 883 case 17: return "Standard light"; 883 884 case 18: return "Standard light (B)"; … … 975 976 if (value == null) 976 977 return null; 977 java.text.DecimalFormat formatter = new DecimalFormat("0.0##");978 DecimalFormat formatter = new DecimalFormat("0.0##"); 978 979 return formatter.format(value.doubleValue()) + " metres"; 979 980 } … … 1018 1019 long apexPower10 = Math.round((double)apexPower * 10.0); 1019 1020 float fApexPower = (float)apexPower10 / 10.0f; 1020 return fApexPower + " sec"; 1021 DecimalFormat format = new DecimalFormat("0.##"); 1022 format.setRoundingMode(RoundingMode.HALF_UP); 1023 return format.format(fApexPower) + " sec"; 1021 1024 } else { 1022 1025 int apexPower = (int)((Math.exp(apexValue * Math.log(2)))); … … 1051 1054 if (value == null) 1052 1055 return null; 1053 return "f/" + SimpleDecimalFormatterWithPrecision.format(value.doubleValue());1056 return getFStopDescription(value.doubleValue()); 1054 1057 } 1055 1058 -
trunk/src/com/drew/metadata/exif/ExifDirectoryBase.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 140 140 public static final int TAG_TILE_BYTE_COUNTS = 0x0145; 141 141 142 /** 143 * Tag is a pointer to one or more sub-IFDs. 144 + Seems to be used exclusively by raw formats, referencing one or two IFDs. 145 */ 142 146 public static final int TAG_SUB_IFD_OFFSET = 0x014a; 143 147 … … 150 154 public static final int TAG_YCBCR_POSITIONING = 0x0213; 151 155 public static final int TAG_REFERENCE_BLACK_WHITE = 0x0214; 156 public static final int TAG_STRIP_ROW_COUNTS = 0x022f; 157 public static final int TAG_APPLICATION_NOTES = 0x02bc; 152 158 153 159 public static final int TAG_RELATED_IMAGE_FILE_FORMAT = 0x1000; … … 260 266 public static final int TAG_METERING_MODE = 0x9207; 261 267 262 public static final int TAG_LIGHT_SOURCE = 0x9208; // TODO duplicate tag263 268 /** 264 269 * White balance (aka light source). '0' means unknown, '1' daylight, … … 267 272 * '22' D75, '255' other. 268 273 */ 269 public static final int TAG_WHITE_BALANCE = 0x9208; // TODO duplicate tag274 public static final int TAG_WHITE_BALANCE = 0x9208; 270 275 /** 271 276 * 0x0 = 0000000 = No Flash … … 600 605 map.put(TAG_ROWS_PER_STRIP, "Rows Per Strip"); 601 606 map.put(TAG_STRIP_BYTE_COUNTS, "Strip Byte Counts"); 602 map.put(TAG_MIN_SAMPLE_VALUE, "Minimum sample value");603 map.put(TAG_MAX_SAMPLE_VALUE, "Maximum sample value");607 map.put(TAG_MIN_SAMPLE_VALUE, "Minimum Sample Value"); 608 map.put(TAG_MAX_SAMPLE_VALUE, "Maximum Sample Value"); 604 609 map.put(TAG_X_RESOLUTION, "X Resolution"); 605 610 map.put(TAG_Y_RESOLUTION, "Y Resolution"); … … 627 632 map.put(TAG_YCBCR_POSITIONING, "YCbCr Positioning"); 628 633 map.put(TAG_REFERENCE_BLACK_WHITE, "Reference Black/White"); 634 map.put(TAG_STRIP_ROW_COUNTS, "Strip Row Counts"); 635 map.put(TAG_APPLICATION_NOTES, "Application Notes"); 629 636 map.put(TAG_RELATED_IMAGE_FILE_FORMAT, "Related Image File Format"); 630 637 map.put(TAG_RELATED_IMAGE_WIDTH, "Related Image Width"); … … 663 670 map.put(TAG_SUBJECT_DISTANCE, "Subject Distance"); 664 671 map.put(TAG_METERING_MODE, "Metering Mode"); 665 map.put(TAG_LIGHT_SOURCE, "Light Source");666 672 map.put(TAG_WHITE_BALANCE, "White Balance"); 667 673 map.put(TAG_FLASH, "Flash"); -
trunk/src/com/drew/metadata/exif/ExifIFD0Descriptor.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/ExifIFD0Directory.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 22 22 package com.drew.metadata.exif; 23 23 24 import java.util.HashMap; 25 24 26 import com.drew.lang.annotations.NotNull; 25 26 import java.util.HashMap;27 27 28 28 /** -
trunk/src/com/drew/metadata/exif/ExifInteropDescriptor.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/ExifInteropDirectory.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/ExifReader.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 28 28 import com.drew.lang.RandomAccessReader; 29 29 import com.drew.lang.annotations.NotNull; 30 import com.drew.lang.annotations.Nullable; 31 import com.drew.metadata.Directory; 30 32 import com.drew.metadata.Metadata; 31 33 32 34 import java.io.IOException; 33 import java.util. Arrays;35 import java.util.Collections; 34 36 35 37 /** … … 60 62 public Iterable<JpegSegmentType> getSegmentTypes() 61 63 { 62 return Arrays.asList(JpegSegmentType.APP1);64 return Collections.singletonList(JpegSegmentType.APP1); 63 65 } 64 66 … … 84 86 public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset) 85 87 { 88 extract(reader, metadata, readerOffset, null); 89 } 90 91 /** Reads TIFF formatted Exif data a specified offset within a {@link RandomAccessReader}. */ 92 public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset, @Nullable Directory parentDirectory) 93 { 86 94 try { 87 95 // Read the TIFF-formatted Exif data 88 96 new TiffReader().processTiff( 89 97 reader, 90 new ExifTiffHandler(metadata, _storeThumbnailBytes ),98 new ExifTiffHandler(metadata, _storeThumbnailBytes, parentDirectory), 91 99 readerOffset 92 100 ); -
trunk/src/com/drew/metadata/exif/ExifSubIFDDescriptor.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/ExifSubIFDDirectory.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 21 21 package com.drew.metadata.exif; 22 22 23 import java.util.Date; 24 import java.util.HashMap; 25 import java.util.TimeZone; 26 23 27 import com.drew.lang.annotations.NotNull; 24 25 import java.util.HashMap; 28 import com.drew.lang.annotations.Nullable; 26 29 27 30 /** … … 61 64 return _tagNameMap; 62 65 } 66 67 /** 68 * Parses the date/time tag and the subsecond tag to obtain a single Date object with milliseconds 69 * representing the date and time when this image was captured. Attempts will be made to parse the 70 * values as though it is in the GMT {@link TimeZone}. 71 * 72 * @return A Date object representing when this image was captured, if possible, otherwise null 73 */ 74 @Nullable 75 public Date getDateOriginal() 76 { 77 return getDateOriginal(null); 78 } 79 80 /** 81 * Parses the date/time tag and the subsecond tag to obtain a single Date object with milliseconds 82 * representing the date and time when this image was captured. Attempts will be made to parse the 83 * values as though it is in the {@link TimeZone} represented by the {@code timeZone} parameter 84 * (if it is non-null). 85 * 86 * @param timeZone the time zone to use 87 * @return A Date object representing when this image was captured, if possible, otherwise null 88 */ 89 @Nullable 90 public Date getDateOriginal(TimeZone timeZone) 91 { 92 return getDate(TAG_DATETIME_ORIGINAL, getString(TAG_SUBSECOND_TIME_ORIGINAL), timeZone); 93 } 94 95 /** 96 * Parses the date/time tag and the subsecond tag to obtain a single Date object with milliseconds 97 * representing the date and time when this image was digitized. Attempts will be made to parse the 98 * values as though it is in the GMT {@link TimeZone}. 99 * 100 * @return A Date object representing when this image was digitized, if possible, otherwise null 101 */ 102 @Nullable 103 public Date getDateDigitized() 104 { 105 return getDateDigitized(null); 106 } 107 108 /** 109 * Parses the date/time tag and the subsecond tag to obtain a single Date object with milliseconds 110 * representing the date and time when this image was digitized. Attempts will be made to parse the 111 * values as though it is in the {@link TimeZone} represented by the {@code timeZone} parameter 112 * (if it is non-null). 113 * 114 * @param timeZone the time zone to use 115 * @return A Date object representing when this image was digitized, if possible, otherwise null 116 */ 117 @Nullable 118 public Date getDateDigitized(TimeZone timeZone) 119 { 120 return getDate(TAG_DATETIME_DIGITIZED, getString(TAG_SUBSECOND_TIME_DIGITIZED), timeZone); 121 } 63 122 } -
trunk/src/com/drew/metadata/exif/ExifThumbnailDescriptor.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 22 22 package com.drew.metadata.exif; 23 23 24 import static com.drew.metadata.exif.ExifThumbnailDirectory.TAG_THUMBNAIL_LENGTH; 25 import static com.drew.metadata.exif.ExifThumbnailDirectory.TAG_THUMBNAIL_OFFSET; 26 24 27 import com.drew.lang.annotations.NotNull; 25 28 import com.drew.lang.annotations.Nullable; 26 27 import static com.drew.metadata.exif.ExifThumbnailDirectory.*;28 29 29 30 /** … … 48 49 case TAG_THUMBNAIL_LENGTH: 49 50 return getThumbnailLengthDescription(); 50 case TAG_THUMBNAIL_COMPRESSION:51 return getCompressionDescription();52 51 default: 53 52 return super.getDescription(tagType); 54 }55 }56 57 @Nullable58 public String getCompressionDescription()59 {60 Integer value = _directory.getInteger(TAG_THUMBNAIL_COMPRESSION);61 if (value == null)62 return null;63 switch (value) {64 case 1: return "Uncompressed";65 case 2: return "CCITT 1D";66 case 3: return "T4/Group 3 Fax";67 case 4: return "T6/Group 4 Fax";68 case 5: return "LZW";69 case 6: return "JPEG (old-style)";70 case 7: return "JPEG";71 case 8: return "Adobe Deflate";72 case 9: return "JBIG B&W";73 case 10: return "JBIG Color";74 case 32766: return "Next";75 case 32771: return "CCIRLEW";76 case 32773: return "PackBits";77 case 32809: return "Thunderscan";78 case 32895: return "IT8CTPAD";79 case 32896: return "IT8LW";80 case 32897: return "IT8MP";81 case 32898: return "IT8BL";82 case 32908: return "PixarFilm";83 case 32909: return "PixarLog";84 case 32946: return "Deflate";85 case 32947: return "DCS";86 case 32661: return "JBIG";87 case 32676: return "SGILog";88 case 32677: return "SGILog24";89 case 32712: return "JPEG 2000";90 case 32713: return "Nikon NEF Compressed";91 default:92 return "Unknown compression";93 53 } 94 54 } -
trunk/src/com/drew/metadata/exif/ExifThumbnailDirectory.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 22 22 package com.drew.metadata.exif; 23 23 24 import java.io.FileOutputStream; 25 import java.io.IOException; 26 import java.util.HashMap; 27 24 28 import com.drew.lang.annotations.NotNull; 25 29 import com.drew.lang.annotations.Nullable; 26 30 import com.drew.metadata.MetadataException; 27 28 import java.io.FileOutputStream;29 import java.io.IOException;30 import java.util.HashMap;31 31 32 32 /** … … 46 46 public static final int TAG_THUMBNAIL_LENGTH = 0x0202; 47 47 48 /**49 * Shows compression method for Thumbnail.50 * 1 = Uncompressed51 * 2 = CCITT 1D52 * 3 = T4/Group 3 Fax53 * 4 = T6/Group 4 Fax54 * 5 = LZW55 * 6 = JPEG (old-style)56 * 7 = JPEG57 * 8 = Adobe Deflate58 * 9 = JBIG B&W59 * 10 = JBIG Color60 * 32766 = Next61 * 32771 = CCIRLEW62 * 32773 = PackBits63 * 32809 = Thunderscan64 * 32895 = IT8CTPAD65 * 32896 = IT8LW66 * 32897 = IT8MP67 * 32898 = IT8BL68 * 32908 = PixarFilm69 * 32909 = PixarLog70 * 32946 = Deflate71 * 32947 = DCS72 * 34661 = JBIG73 * 34676 = SGILog74 * 34677 = SGILog2475 * 34712 = JPEG 200076 * 34713 = Nikon NEF Compressed77 */78 public static final int TAG_THUMBNAIL_COMPRESSION = 0x0103;79 80 48 @NotNull 81 49 protected static final HashMap<Integer, String> _tagNameMap = new HashMap<Integer, String>(); … … 85 53 addExifTagNames(_tagNameMap); 86 54 87 _tagNameMap.put(TAG_THUMBNAIL_COMPRESSION, "Thumbnail Compression");88 55 _tagNameMap.put(TAG_THUMBNAIL_OFFSET, "Thumbnail Offset"); 89 56 _tagNameMap.put(TAG_THUMBNAIL_LENGTH, "Thumbnail Length"); -
trunk/src/com/drew/metadata/exif/ExifTiffHandler.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 26 26 import com.drew.lang.SequentialByteArrayReader; 27 27 import com.drew.lang.annotations.NotNull; 28 import com.drew.lang.annotations.Nullable; 28 29 import com.drew.metadata.Directory; 29 30 import com.drew.metadata.Metadata; … … 47 48 private final boolean _storeThumbnailBytes; 48 49 49 public ExifTiffHandler(@NotNull Metadata metadata, boolean storeThumbnailBytes )50 public ExifTiffHandler(@NotNull Metadata metadata, boolean storeThumbnailBytes, @Nullable Directory parentDirectory) 50 51 { 51 52 super(metadata, ExifIFD0Directory.class); 52 53 _storeThumbnailBytes = storeThumbnailBytes; 54 55 if (parentDirectory != null) 56 _currentDirectory.setParent(parentDirectory); 53 57 } 54 58 … … 65 69 } 66 70 67 public boolean isTagIfdPointer(int tagType)68 { 69 if (tag Type == ExifIFD0Directory.TAG_EXIF_SUB_IFD_OFFSET && _currentDirectory instanceof ExifIFD0Directory) {71 public boolean tryEnterSubIfd(int tagId) 72 { 73 if (tagId == ExifDirectoryBase.TAG_SUB_IFD_OFFSET) { 70 74 pushDirectory(ExifSubIFDDirectory.class); 71 75 return true; 72 } else if (tagType == ExifIFD0Directory.TAG_GPS_INFO_OFFSET && _currentDirectory instanceof ExifIFD0Directory) { 73 pushDirectory(GpsDirectory.class); 74 return true; 75 } else if (tagType == ExifSubIFDDirectory.TAG_INTEROP_OFFSET && _currentDirectory instanceof ExifSubIFDDirectory) { 76 pushDirectory(ExifInteropDirectory.class); 77 return true; 76 } 77 78 if (_currentDirectory instanceof ExifIFD0Directory) { 79 if (tagId == ExifIFD0Directory.TAG_EXIF_SUB_IFD_OFFSET) { 80 pushDirectory(ExifSubIFDDirectory.class); 81 return true; 82 } 83 84 if (tagId == ExifIFD0Directory.TAG_GPS_INFO_OFFSET) { 85 pushDirectory(GpsDirectory.class); 86 return true; 87 } 88 } 89 90 if (_currentDirectory instanceof ExifSubIFDDirectory) { 91 if (tagId == ExifSubIFDDirectory.TAG_INTEROP_OFFSET) { 92 pushDirectory(ExifInteropDirectory.class); 93 return true; 94 } 95 } 96 97 if (_currentDirectory instanceof OlympusMakernoteDirectory) { 98 if (tagId == OlympusMakernoteDirectory.TAG_EQUIPMENT) { 99 pushDirectory(OlympusEquipmentMakernoteDirectory.class); 100 return true; 101 } 102 103 if (tagId == OlympusMakernoteDirectory.TAG_CAMERA_SETTINGS) { 104 pushDirectory(OlympusCameraSettingsMakernoteDirectory.class); 105 return true; 106 } 78 107 } 79 108 … … 96 125 // NOTE have seen the CanonMakernoteDirectory IFD have a follower pointer, but it points to invalid data. 97 126 return false; 127 } 128 129 @Nullable 130 public Long tryCustomProcessFormat(final int tagId, final int formatCode, final long componentCount) 131 { 132 if (formatCode == 13) 133 return componentCount * 4; 134 135 return null; 98 136 } 99 137 … … 115 153 if (reader.getInt8(tagOffset) == 0x1c) { 116 154 final byte[] iptcBytes = reader.getBytes(tagOffset, byteCount); 117 new IptcReader().extract(new SequentialByteArrayReader(iptcBytes), _metadata, iptcBytes.length );155 new IptcReader().extract(new SequentialByteArrayReader(iptcBytes), _metadata, iptcBytes.length, _currentDirectory); 118 156 return true; 119 157 } … … 129 167 // after the extraction process, if we have the correct tags, we may be able to store thumbnail information 130 168 ExifThumbnailDirectory thumbnailDirectory = _metadata.getFirstDirectoryOfType(ExifThumbnailDirectory.class); 131 if (thumbnailDirectory != null && thumbnailDirectory.containsTag(ExifThumbnailDirectory.TAG_ THUMBNAIL_COMPRESSION)) {169 if (thumbnailDirectory != null && thumbnailDirectory.containsTag(ExifThumbnailDirectory.TAG_COMPRESSION)) { 132 170 Integer offset = thumbnailDirectory.getInteger(ExifThumbnailDirectory.TAG_THUMBNAIL_OFFSET); 133 171 Integer length = thumbnailDirectory.getInteger(ExifThumbnailDirectory.TAG_THUMBNAIL_LENGTH); … … 164 202 final String firstSevenChars = reader.getString(makernoteOffset, 7); 165 203 final String firstEightChars = reader.getString(makernoteOffset, 8); 204 final String firstTenChars = reader.getString(makernoteOffset, 10); 166 205 final String firstTwelveChars = reader.getString(makernoteOffset, 12); 167 206 168 207 boolean byteOrderBefore = reader.isMotorolaByteOrder(); 169 208 170 if ("OLYMP ".equals(firstFiveChars) || "EPSON".equals(firstFiveChars) || "AGFA".equals(firstFourChars)) {209 if ("OLYMP\0".equals(firstSixChars) || "EPSON".equals(firstFiveChars) || "AGFA".equals(firstFourChars)) { 171 210 // Olympus Makernote 172 211 // Epson and Agfa use Olympus makernote standard: http://www.ozhiker.com/electronics/pjmt/jpeg_info/ 173 212 pushDirectory(OlympusMakernoteDirectory.class); 174 213 TiffReader.processIfd(this, reader, processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset); 214 } else if ("OLYMPUS\0II".equals(firstTenChars)) { 215 // Olympus Makernote (alternate) 216 // Note that data is relative to the beginning of the makernote 217 // http://exiv2.org/makernote.html 218 pushDirectory(OlympusMakernoteDirectory.class); 219 TiffReader.processIfd(this, reader, processedIfdOffsets, makernoteOffset + 12, makernoteOffset); 175 220 } else if (cameraMake != null && cameraMake.toUpperCase().startsWith("MINOLTA")) { 176 221 // Cases seen with the model starting with MINOLTA in capitals seem to have a valid Olympus makernote -
trunk/src/com/drew/metadata/exif/GpsDescriptor.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 110 110 // time in hour, min, sec 111 111 Rational[] timeComponents = _directory.getRationalArray(TAG_TIME_STAMP); 112 DecimalFormat df = new DecimalFormat("00.00 ");112 DecimalFormat df = new DecimalFormat("00.000"); 113 113 return timeComponents == null 114 114 ? null -
trunk/src/com/drew/metadata/exif/GpsDirectory.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 26 26 import com.drew.lang.annotations.Nullable; 27 27 28 import java.text.DateFormat; 29 import java.text.ParseException; 30 import java.text.SimpleDateFormat; 31 import java.util.Date; 28 32 import java.util.HashMap; 33 import java.util.Locale; 29 34 30 35 /** … … 164 169 public GeoLocation getGeoLocation() 165 170 { 166 Rational[] latitudes = getRationalArray( GpsDirectory.TAG_LATITUDE);167 Rational[] longitudes = getRationalArray( GpsDirectory.TAG_LONGITUDE);168 String latitudeRef = getString( GpsDirectory.TAG_LATITUDE_REF);169 String longitudeRef = getString( GpsDirectory.TAG_LONGITUDE_REF);171 Rational[] latitudes = getRationalArray(TAG_LATITUDE); 172 Rational[] longitudes = getRationalArray(TAG_LONGITUDE); 173 String latitudeRef = getString(TAG_LATITUDE_REF); 174 String longitudeRef = getString(TAG_LONGITUDE_REF); 170 175 171 176 // Make sure we have the required values … … 186 191 return new GeoLocation(lat, lon); 187 192 } 193 194 /** 195 * Parses the date stamp tag and the time stamp tag to obtain a single Date object representing the 196 * date and time when this image was captured. 197 * 198 * @return A Date object representing when this image was captured, if possible, otherwise null 199 */ 200 @Nullable 201 public Date getGpsDate() 202 { 203 String date = getString(TAG_DATE_STAMP); 204 Rational[] timeComponents = getRationalArray(TAG_TIME_STAMP); 205 206 // Make sure we have the required values 207 if (date == null) 208 return null; 209 if (timeComponents == null || timeComponents.length != 3) 210 return null; 211 212 String dateTime = String.format(Locale.US, "%s %02d:%02d:%02.3f UTC", 213 date, timeComponents[0].intValue(), timeComponents[1].intValue(), timeComponents[2].doubleValue()); 214 try { 215 DateFormat parser = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss.S z"); 216 return parser.parse(dateTime); 217 } catch (ParseException e) { 218 return null; 219 } 220 } 188 221 } -
trunk/src/com/drew/metadata/exif/makernotes/CanonMakernoteDescriptor.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 24 24 import com.drew.lang.annotations.Nullable; 25 25 import com.drew.metadata.TagDescriptor; 26 27 import java.text.DecimalFormat; 26 28 27 29 import static com.drew.metadata.exif.makernotes.CanonMakernoteDirectory.*; … … 138 140 public String getSerialNumberDescription() 139 141 { 142 // http://www.ozhiker.com/electronics/pjmt/jpeg_info/canon_mn.html 140 143 Integer value = _directory.getInteger(TAG_CANON_SERIAL_NUMBER); 141 144 if (value == null) … … 673 676 return "Self timer not used"; 674 677 } else { 675 // TODO find an image that tests this calculation676 return Double.toString((double)value * 0.1d) + " sec";678 DecimalFormat format = new DecimalFormat("0.##"); 679 return format.format((double)value * 0.1d) + " sec"; 677 680 } 678 681 } -
trunk/src/com/drew/metadata/exif/makernotes/CanonMakernoteDirectory.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/CasioType1MakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 155 155 { 156 156 Integer value = _directory.getInteger(TAG_OBJECT_DISTANCE); 157 158 if (value == null) 159 return null; 160 161 return value + " mm"; 157 return value == null ? null : getFocalLengthDescription(value); 162 158 } 163 159 -
trunk/src/com/drew/metadata/exif/makernotes/CasioType1MakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/CasioType2MakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 240 240 { 241 241 Double value = _directory.getDoubleObject(TAG_FOCAL_LENGTH); 242 if (value == null) 243 return null; 244 return Double.toString(value / 10d) + " mm"; 242 return value == null ? null : getFocalLengthDescription(value / 10d); 245 243 } 246 244 -
trunk/src/com/drew/metadata/exif/makernotes/CasioType2MakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/FujifilmMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/FujifilmMakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/KodakMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/KodakMakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/KyoceraMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/KyoceraMakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/LeicaMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/LeicaMakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/NikonType1MakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/NikonType1MakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/NikonType2MakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 306 306 { 307 307 int[] values = _directory.getIntArray(tagType); 308 if (values == null )308 if (values == null || values.length < 2) 309 309 return null; 310 310 if (values.length < 3 || values[2] == 0) … … 329 329 public String getLensDescription() 330 330 { 331 Rational[] values = _directory.getRationalArray(TAG_LENS); 332 333 return values == null 334 ? null 335 : values.length < 4 336 ? _directory.getString(TAG_LENS) 337 : String.format("%d-%dmm f/%.1f-%.1f", values[0].intValue(), values[1].intValue(), values[2].floatValue(), values[3].floatValue()); 338 331 return getLensSpecificationDescription(TAG_LENS); 339 332 } 340 333 -
trunk/src/com/drew/metadata/exif/makernotes/NikonType2MakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/OlympusMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 21 21 package com.drew.metadata.exif.makernotes; 22 22 23 import com.drew.lang.DateUtil; 23 24 import com.drew.lang.annotations.NotNull; 24 25 import com.drew.lang.annotations.Nullable; 25 26 import com.drew.metadata.TagDescriptor; 26 27 27 import java.util.GregorianCalendar; 28 import java.math.RoundingMode; 29 import java.text.DecimalFormat; 28 30 29 31 import static com.drew.metadata.exif.makernotes.OlympusMakernoteDirectory.*; … … 115 117 return getFocusDistanceDescription(); 116 118 case CameraSettings.TAG_FLASH_FIRED: 117 return getFlas tFiredDescription();119 return getFlashFiredDescription(); 118 120 case CameraSettings.TAG_DATE: 119 121 return getDateDescription(); … … 142 144 return getSubjectProgramDescription(); 143 145 case CameraSettings.TAG_FLASH_COMPENSATION: 144 return getFlas tCompensationDescription();146 return getFlashCompensationDescription(); 145 147 case CameraSettings.TAG_ISO_SETTING: 146 148 return getIsoSettingDescription(); … … 258 260 259 261 double iso = Math.pow((value / 8d) - 1, 2) * 3.125; 260 return Double.toString(iso); 262 DecimalFormat format = new DecimalFormat("0.##"); 263 format.setRoundingMode(RoundingMode.HALF_UP); 264 return format.format(iso); 261 265 } 262 266 … … 274 278 275 279 double shutterSpeed = Math.pow((49-value) / 8d, 2); 276 return Double.toString(shutterSpeed) + " sec"; 280 DecimalFormat format = new DecimalFormat("0.###"); 281 format.setRoundingMode(RoundingMode.HALF_UP); 282 return format.format(shutterSpeed) + " sec"; 277 283 } 278 284 … … 289 295 290 296 double fStop = Math.pow((value/16d) - 0.5, 2); 291 return "F" + Double.toString(fStop);297 return getFStopDescription(fStop); 292 298 } 293 299 … … 308 314 { 309 315 Long value = _directory.getLongObject(CameraSettings.TAG_EXPOSURE_COMPENSATION); 310 return value == null ? null : ((value / 3d) - 2) + " EV"; 316 DecimalFormat format = new DecimalFormat("0.##"); 317 return value == null ? null : format.format((value / 3d) - 2) + " EV"; 311 318 } 312 319 … … 341 348 { 342 349 Long value = _directory.getLongObject(CameraSettings.TAG_FOCAL_LENGTH); 343 return value == null ? null : Double.toString(value/256d) + " mm";350 return value == null ? null : getFocalLengthDescription(value/256d); 344 351 } 345 352 … … 356 363 357 364 @Nullable 358 public String getFlas tFiredDescription()365 public String getFlashFiredDescription() 359 366 { 360 367 return getIndexedDescription(CameraSettings.TAG_FLASH_FIRED, "No", "Yes"); … … 370 377 if (value == null) 371 378 return null; 372 long day = value & 0xFF; 373 long month = (value >> 16) & 0xFF; 374 long year = (value >> 8) & 0xFF; 375 return new GregorianCalendar((int)year + 1970, (int)month, (int)day).getTime().toString(); 379 380 int day = (int) (value & 0xFF); 381 int month = (int) ((value >> 16) & 0xFF); 382 int year = (int) ((value >> 8) & 0xFF) + 1970; 383 384 if (!DateUtil.isValidDate(year, month, day)) 385 return "Invalid date"; 386 387 return String.format("%04d-%02d-%02d", year, month + 1, day); 376 388 } 377 389 … … 385 397 if (value == null) 386 398 return null; 387 long hours = (value >> 8) & 0xFF; 388 long minutes = (value >> 16) & 0xFF; 389 long seconds = value & 0xFF; 399 400 int hours = (int) ((value >> 8) & 0xFF); 401 int minutes = (int) ((value >> 16) & 0xFF); 402 int seconds = (int) (value & 0xFF); 403 404 if (!DateUtil.isValidTime(hours, minutes, seconds)) 405 return "Invalid time"; 390 406 391 407 return String.format("%02d:%02d:%02d", hours, minutes, seconds); … … 400 416 return null; 401 417 double fStop = Math.pow((value/16d) - 0.5, 2); 402 return "F" + fStop;418 return getFStopDescription(fStop); 403 419 } 404 420 … … 424 440 { 425 441 Long value = _directory.getLongObject(CameraSettings.TAG_WHITE_BALANCE_RED); 426 return value == null ? null : Double.toString(value/256d); 442 DecimalFormat format = new DecimalFormat("0.##"); 443 return value == null ? null : format.format(value/256d); 427 444 } 428 445 … … 431 448 { 432 449 Long value = _directory.getLongObject(CameraSettings.TAG_WHITE_BALANCE_GREEN); 433 return value == null ? null : Double.toString(value/256d); 450 DecimalFormat format = new DecimalFormat("0.##"); 451 return value == null ? null : format.format(value/256d); 434 452 } 435 453 … … 438 456 { 439 457 Long value = _directory.getLongObject(CameraSettings.TAG_WHITE_BALANCE_BLUE); 440 return value == null ? null : Double.toString(value/256d); 458 DecimalFormat format = new DecimalFormat("0.##"); 459 return value == null ? null : format.format(value / 256d); 441 460 } 442 461 … … 468 487 469 488 @Nullable 470 public String getFlas tCompensationDescription()489 public String getFlashCompensationDescription() 471 490 { 472 491 Long value = _directory.getLongObject(CameraSettings.TAG_FLASH_COMPENSATION); 473 return value == null ? null : ((value-6)/3d) + " EV"; 492 DecimalFormat format = new DecimalFormat("0.##"); 493 return value == null ? null : format.format((value-6)/3d) + " EV"; 474 494 } 475 495 … … 535 555 { 536 556 Long value = _directory.getLongObject(CameraSettings.TAG_APEX_BRIGHTNESS_VALUE); 537 return value == null ? null : Double.toString((value/8d)-6); 557 DecimalFormat format = new DecimalFormat("0.##"); 558 return value == null ? null : format.format((value/8d)-6); 538 559 } 539 560 -
trunk/src/com/drew/metadata/exif/makernotes/OlympusMakernoteDirectory.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/PanasonicMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/PanasonicMakernoteDirectory.java
r8243 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/PentaxMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/PentaxMakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/RicohMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/RicohMakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/SanyoMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/SanyoMakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/SigmaMakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/SigmaMakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/SonyType1MakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/SonyType1MakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/SonyType6MakernoteDescriptor.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/SonyType6MakernoteDirectory.java
r8132 r10862 1 1 /* 2 * Copyright 2002-201 5Drew Noakes2 * Copyright 2002-2016 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/makernotes/package.html
r8132 r10862 1 1 <!-- 2 ~ Copyright 2002-201 5Drew Noakes2 ~ Copyright 2002-2016 Drew Noakes 3 3 ~ 4 4 ~ Licensed under the Apache License, Version 2.0 (the "License"); -
trunk/src/com/drew/metadata/exif/package.html
r8132 r10862 1 1 <!-- 2 ~ Copyright 2002-201 5Drew Noakes2 ~ Copyright 2002-2016 Drew Noakes 3 3 ~ 4 4 ~ Licensed under the Apache License, Version 2.0 (the "License");
Note:
See TracChangeset
for help on using the changeset viewer.