]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/jpeg/ExternalExifLibrary.java
Version 10, May 2010
[GpsPrune.git] / tim / prune / jpeg / ExternalExifLibrary.java
diff --git a/tim/prune/jpeg/ExternalExifLibrary.java b/tim/prune/jpeg/ExternalExifLibrary.java
new file mode 100644 (file)
index 0000000..b9cd1fd
--- /dev/null
@@ -0,0 +1,120 @@
+package tim.prune.jpeg;
+
+import java.io.File;
+
+import com.drew.lang.Rational;
+import com.drew.metadata.Directory;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.exif.ExifDirectory;
+import com.drew.metadata.exif.ExifReader;
+import com.drew.metadata.exif.GpsDirectory;
+
+/**
+ * Class to act as a gateway into the external exif library functions.
+ * This should be the only class with dependence on the lib-metadata-extractor-java
+ * classes (which are NOT delivered with Prune).
+ * This class will not compile without this extra dependency (but is not required if
+ * the ExifGateway uses the InternalExifLibrary instead).
+ * Should not be included if the internal library will be used (from jpeg.drew package).
+ */
+public class ExternalExifLibrary implements ExifLibrary
+{
+       /**
+        * Use the _external_ exif library to get the data from the given file
+        * @param inFile file to access
+        * @return Jpeg data if available, otherwise null
+        */
+       public JpegData getJpegData(File inFile)
+       {
+               JpegData data = new JpegData();
+               // Read exif data from picture
+               try
+               {
+                       Metadata metadata = new Metadata();
+                       new ExifReader(inFile).extract(metadata);
+                       if (metadata.containsDirectory(GpsDirectory.class))
+                       {
+                               Directory gpsdir = metadata.getDirectory(GpsDirectory.class);
+                               if (gpsdir.containsTag(GpsDirectory.TAG_GPS_LATITUDE)
+                                       && gpsdir.containsTag(GpsDirectory.TAG_GPS_LONGITUDE)
+                                       && gpsdir.containsTag(GpsDirectory.TAG_GPS_LATITUDE_REF)
+                                       && gpsdir.containsTag(GpsDirectory.TAG_GPS_LONGITUDE_REF))
+                               {
+                                       data.setLatitudeRef(gpsdir.getString(GpsDirectory.TAG_GPS_LATITUDE_REF));
+                                       Rational[] latRats = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_LATITUDE);
+                                       data.setLatitude(new double[] {latRats[0].doubleValue(),
+                                               latRats[1].doubleValue(), latRats[2].doubleValue()});
+                                       data.setLongitudeRef(gpsdir.getString(GpsDirectory.TAG_GPS_LONGITUDE_REF));
+                                       Rational[] lonRats = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE);
+                                       data.setLongitude(new double[] {lonRats[0].doubleValue(),
+                                               lonRats[1].doubleValue(), lonRats[2].doubleValue()});
+                               }
+
+                               // Altitude (if present)
+                               if (gpsdir.containsTag(GpsDirectory.TAG_GPS_ALTITUDE) && gpsdir.containsTag(GpsDirectory.TAG_GPS_ALTITUDE_REF))
+                               {
+                                       data.setAltitude(gpsdir.getRational(GpsDirectory.TAG_GPS_ALTITUDE).intValue());
+                                       byte altRef = (byte) gpsdir.getInt(GpsDirectory.TAG_GPS_ALTITUDE_REF);
+                                       data.setAltitudeRef(altRef);
+                               }
+
+                               // Timestamp and datestamp (if present)
+                               final int TAG_GPS_DATESTAMP = 0x001d;
+                               if (gpsdir.containsTag(GpsDirectory.TAG_GPS_TIME_STAMP) && gpsdir.containsTag(TAG_GPS_DATESTAMP))
+                               {
+                                       Rational[] times = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_TIME_STAMP);
+                                       data.setGpsTimestamp(new int[] {times[0].intValue(), times[1].intValue(),
+                                               times[2].intValue()});
+                                       Rational[] dates = gpsdir.getRationalArray(TAG_GPS_DATESTAMP);
+                                       data.setGpsDatestamp(new int[] {dates[0].intValue(), dates[1].intValue(), dates[2].intValue()});
+                               }
+                       }
+
+                       // Tags from Exif directory
+                       if (metadata.containsDirectory(ExifDirectory.class))
+                       {
+                               Directory exifdir = metadata.getDirectory(ExifDirectory.class);
+
+                               // Take time and date from exif tags if haven't got it already from GPS
+                               if (data.getGpsDatestamp() == null && exifdir.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
+                                       data.setOriginalTimestamp(exifdir.getString(ExifDirectory.TAG_DATETIME_ORIGINAL));
+                               }
+
+                               // Photo rotation code
+                               if (exifdir.containsTag(ExifDirectory.TAG_ORIENTATION)) {
+                                       data.setOrientationCode(exifdir.getInt(ExifDirectory.TAG_ORIENTATION));
+                                       // NOTE: this presumably takes the _last_ orientation value found, not the first.
+                               }
+
+                               // Thumbnail
+                               if (exifdir.containsTag(ExifDirectory.TAG_THUMBNAIL_DATA))
+                               {
+                                       // Make a copy of the byte data rather than keeping a reference to extracted array
+                                       byte[] tdata = exifdir.getByteArray(ExifDirectory.TAG_THUMBNAIL_DATA);
+                                       byte[] thumb = new byte[tdata.length];
+                                       System.arraycopy(tdata, 0, thumb, 0, tdata.length);
+                                       data.setThumbnailImage(thumb);
+                               }
+                       }
+
+               }
+               catch (Exception e) {
+                       // Exception reading metadata, just ignore it
+               }
+               return data;
+       }
+
+       /**
+        * Check whether the exifreader class can be correctly resolved
+        * @return true if it looks ok
+        */
+       public boolean looksOK()
+       {
+               try {
+                       String test = ExifReader.class.getName();
+                       if (test != null) return true;
+               }
+               catch (LinkageError le) {}
+               return false;
+       }
+}