]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/jpeg/ExternalExifLibrary.java
cff2346e531dff458d4b91a1a49822a270087d51
[GpsPrune.git] / tim / prune / jpeg / ExternalExifLibrary.java
1 package tim.prune.jpeg;
2
3 import java.io.File;
4
5 import com.drew.lang.Rational;
6 import com.drew.metadata.Directory;
7 import com.drew.metadata.Metadata;
8 import com.drew.metadata.exif.ExifDirectory;
9 import com.drew.metadata.exif.ExifReader;
10 import com.drew.metadata.exif.GpsDirectory;
11
12 /**
13  * Class to act as a gateway into the external exif library functions.
14  * This should be the only class with dependence on the lib-metadata-extractor-java
15  * classes (which are NOT delivered with Prune).
16  * This class will not compile without this extra dependency (but is not required if
17  * the ExifGateway uses the InternalExifLibrary instead).
18  * Should not be included if the internal library will be used (from jpeg.drew package).
19  */
20 public class ExternalExifLibrary implements ExifLibrary
21 {
22         /**
23          * Use the _external_ exif library to get the data from the given file
24          * @param inFile file to access
25          * @return Jpeg data if available, otherwise null
26          */
27         public JpegData getJpegData(File inFile)
28         {
29                 JpegData data = new JpegData();
30                 // Read exif data from picture
31                 try
32                 {
33                         Metadata metadata = new Metadata();
34                         new ExifReader(inFile).extract(metadata);
35                         if (metadata.containsDirectory(GpsDirectory.class))
36                         {
37                                 Directory gpsdir = metadata.getDirectory(GpsDirectory.class);
38                                 if (gpsdir.containsTag(GpsDirectory.TAG_GPS_LATITUDE)
39                                         && gpsdir.containsTag(GpsDirectory.TAG_GPS_LONGITUDE)
40                                         && gpsdir.containsTag(GpsDirectory.TAG_GPS_LATITUDE_REF)
41                                         && gpsdir.containsTag(GpsDirectory.TAG_GPS_LONGITUDE_REF))
42                                 {
43                                         data.setLatitudeRef(gpsdir.getString(GpsDirectory.TAG_GPS_LATITUDE_REF));
44                                         Rational[] latRats = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_LATITUDE);
45                                         double seconds = ExifGateway.convertToPositiveValue(latRats[2].getNumerator(), latRats[2].getDenominator());
46                                         data.setLatitude(new double[] {latRats[0].doubleValue(),
47                                                 latRats[1].doubleValue(), seconds});
48                                         data.setLongitudeRef(gpsdir.getString(GpsDirectory.TAG_GPS_LONGITUDE_REF));
49                                         Rational[] lonRats = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE);
50                                         seconds = ExifGateway.convertToPositiveValue(lonRats[2].getNumerator(), lonRats[2].getDenominator());
51                                         data.setLongitude(new double[] {lonRats[0].doubleValue(),
52                                                 lonRats[1].doubleValue(), seconds});
53                                 }
54
55                                 // Altitude (if present)
56                                 if (gpsdir.containsTag(GpsDirectory.TAG_GPS_ALTITUDE) && gpsdir.containsTag(GpsDirectory.TAG_GPS_ALTITUDE_REF))
57                                 {
58                                         data.setAltitude(gpsdir.getRational(GpsDirectory.TAG_GPS_ALTITUDE).intValue());
59                                         byte altRef = (byte) gpsdir.getInt(GpsDirectory.TAG_GPS_ALTITUDE_REF);
60                                         data.setAltitudeRef(altRef);
61                                 }
62
63                                 // Timestamp and datestamp (if present)
64                                 final int TAG_GPS_DATESTAMP = 0x001d;
65                                 if (gpsdir.containsTag(GpsDirectory.TAG_GPS_TIME_STAMP) && gpsdir.containsTag(TAG_GPS_DATESTAMP))
66                                 {
67                                         Rational[] times = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_TIME_STAMP);
68                                         data.setGpsTimestamp(new int[] {times[0].intValue(), times[1].intValue(),
69                                                 times[2].intValue()});
70                                         Rational[] dates = gpsdir.getRationalArray(TAG_GPS_DATESTAMP);
71                                         if (dates != null) {
72                                                 data.setGpsDatestamp(new int[] {dates[0].intValue(), dates[1].intValue(), dates[2].intValue()});
73                                         }
74                                 }
75                         }
76
77                         // Tags from Exif directory
78                         if (metadata.containsDirectory(ExifDirectory.class))
79                         {
80                                 Directory exifdir = metadata.getDirectory(ExifDirectory.class);
81
82                                 // Take time and date from exif tags
83                                 if (exifdir.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
84                                         data.setOriginalTimestamp(exifdir.getString(ExifDirectory.TAG_DATETIME_ORIGINAL));
85                                 }
86                                 // Also take "digitized" timestamp
87                                 if (exifdir.containsTag(ExifDirectory.TAG_DATETIME_DIGITIZED)) {
88                                         data.setDigitizedTimestamp(exifdir.getString(ExifDirectory.TAG_DATETIME_DIGITIZED));
89                                 }
90
91                                 // Photo rotation code
92                                 if (exifdir.containsTag(ExifDirectory.TAG_ORIENTATION)) {
93                                         data.setOrientationCode(exifdir.getInt(ExifDirectory.TAG_ORIENTATION));
94                                         // NOTE: this presumably takes the _last_ orientation value found, not the first.
95                                 }
96
97                                 // Thumbnail
98                                 if (exifdir.containsTag(ExifDirectory.TAG_THUMBNAIL_DATA))
99                                 {
100                                         // Make a copy of the byte data rather than keeping a reference to extracted array
101                                         byte[] tdata = exifdir.getByteArray(ExifDirectory.TAG_THUMBNAIL_DATA);
102                                         byte[] thumb = new byte[tdata.length];
103                                         System.arraycopy(tdata, 0, thumb, 0, tdata.length);
104                                         data.setThumbnailImage(thumb);
105                                 }
106                         }
107
108                 }
109                 catch (Exception e) {
110                         // Exception reading metadata, just ignore it
111                 }
112                 return data;
113         }
114
115
116         /**
117          * Check whether the exifreader class can be correctly resolved
118          * @return true if it looks ok
119          */
120         public boolean looksOK()
121         {
122                 try {
123                         String test = ExifReader.class.getName();
124                         if (test != null) return true;
125                 }
126                 catch (LinkageError le) {}
127                 return false;
128         }
129 }