package net.sourceforge.gpstools.exif;
/* gpsdings
* Copyright (C) 2006 Moritz Ringler
* $Id: MetadataExtractorExifReader.java 360 2008-11-24 19:14:32Z ringler $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.math.BigDecimal;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.metadata.Metadata;
import com.drew.metadata.Directory;
import com.drew.metadata.jpeg.JpegDirectory;
import com.drew.metadata.jpeg.JpegReader;
import com.drew.metadata.MetadataException;
import com.drew.metadata.exif.ExifDirectory;
import com.drew.metadata.exif.GpsDirectory;
import com.drew.metadata.exif.ExifReader;
import com.drew.lang.Rational;
import net.sourceforge.gpstools.gpx.Wpt;
/** @deprecated this class is no longer maintained. Use MediaUtilExifReader instead. */
final class MetadataExtractorExifReader extends AbstractExifReader{
public MetadataExtractorExifReader(){
}
public Date readOriginalTime(File jpeg) throws IOException, ParseException{
String dateString = null;
try{
Metadata meta = (new ExifReader(jpeg)).extract();
ExifDirectory exif = (ExifDirectory) meta.getDirectory(ExifDirectory.class);
dateString = exif.getString(ExifDirectory.TAG_DATETIME_ORIGINAL);
} catch (JpegProcessingException ex){
throw toIOException(ex, jpeg);
}
//interpret the dateString as an UTC dateTime value
return parseExifDate(dateString);
}
private static IOException toIOException(Throwable t, File f){
IOException ex = new IOException("Error reading exif tag from file " + f.getPath());
ex.initCause(t);
return ex;
}
public Wpt readGPSTag(File jpeg) throws IOException, ParseException{
Wpt result = null;
try{
Metadata meta = (new ExifReader(jpeg)).extract();
boolean hasGpsDirectory = meta.containsDirectory(GpsDirectory.class);
if(hasGpsDirectory){
GpsDirectory gps = (GpsDirectory) meta.getDirectory(GpsDirectory.class);
if(gps.hasErrors()){
System.err.println("Warning: GPS directory has errors");
java.util.Iterator it = gps.getErrors();
while(it.hasNext()){
System.out.println(it.next());
}
}
java.util.Iterator tagiter = gps.getTagIterator();
int i = 0;
while(tagiter.hasNext()){
tagiter.next();
i++;
}
if(i == 0){
hasGpsDirectory = false;
} else {
result = wptFromGpsTag(gps);
}
}
if (!hasGpsDirectory) {
System.err.println("Warning no dedicated GPS directory found. Looking for GPS info in main Exif directory.");
Directory dir = meta.getDirectory(ExifDirectory.class);
if(dir.hasErrors()){
System.err.println("Warning: Exif directory has errors.");
java.util.Iterator it = dir.getErrors();
while(it.hasNext()){
System.out.println(it.next());
}
}
result = wptFromGpsTag(dir);
}
} catch (JpegProcessingException ex){
throw toIOException(ex, jpeg);
} catch (MetadataException ex){
throw toIOException(ex, jpeg);
}
if(result == null){
throw new ParseException("No GPS information found in " + jpeg.getPath(),0);
} else {
try{
result.setTime(readOriginalUTCTime(jpeg));
} catch (Exception ex){
throw new Error(ex);
}
}
return result;
}
private static Wpt wptFromGpsTag(Directory gps) throws MetadataException{
Wpt result = null;
if(!gps.containsTag(GpsDirectory.TAG_GPS_LATITUDE)){
throw new MetadataException("GPS latitude missing.");
}
if(!gps.containsTag(GpsDirectory.TAG_GPS_LATITUDE_REF)){
throw new MetadataException("GPS latitude reference missing.");
}
if(!gps.containsTag(GpsDirectory.TAG_GPS_LONGITUDE)){
throw new MetadataException("GPS longitude missing.");
}
if(!gps.containsTag(GpsDirectory.TAG_GPS_LONGITUDE_REF)){
throw new MetadataException("GPS longitude reference missing.");
}
result = new Wpt();
result.setLat(
asBigDecimal(
gps.getRationalArray(GpsDirectory.TAG_GPS_LATITUDE),
gps.getString(GpsDirectory.TAG_GPS_LATITUDE_REF)));
result.setLon(
asBigDecimal(
gps.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE),
gps.getString(GpsDirectory.TAG_GPS_LONGITUDE_REF)));
if(gps.containsTag(GpsDirectory.TAG_GPS_ALTITUDE)){
result.setEle(new BigDecimal(
gps.getDouble(GpsDirectory.TAG_GPS_ALTITUDE)));
}
//cannot do this because GpsDirectory does not know about
//GPS_DATE_STAMP
//if(gps.containsTag(GpsDirectory.TAG_GPS_TIME_STAMP) &&
// gps.containsTag(GpsDirectory.TAG_GPS_DATE_STAMP))
return result;
}
public Dimension readJPEGDimension(File f) throws IOException{
Dimension result = null;
try{
JpegDirectory meta = (JpegDirectory)
(new JpegReader(f)).extract().getDirectory(JpegDirectory.class);
if(
meta != null &&
meta.containsTag(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT) &&
meta.containsTag(JpegDirectory.TAG_JPEG_IMAGE_WIDTH)
){
int height = meta.getInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT);
int width = meta.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH);
result = new Dimension(width, height);
}
} catch (JpegProcessingException ex){
throw toIOException(ex, f);
} catch (MetadataException ex){
throw toIOException(ex, f);
}
return result;
}
private static BigDecimal asBigDecimal(Rational[] latlon, String ref){
double factor = 1.;
double result = 0;
for(Rational r : latlon){
result += r.doubleValue() * factor;
factor /= 60.;
}
if("W".equals(ref) || "S".equals(ref)){
result = -result;
}
return new BigDecimal(result);
}
}