package org.horaapps.leafpic.data;
import android.graphics.BitmapFactory;
import android.util.Log;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.lang.GeoLocation;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifDirectoryBase;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import com.drew.metadata.exif.GpsDirectory;
import com.drew.metadata.xmp.XmpDirectory;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
/**
* Created by dnld on 14/08/16.
*/
class MetadataItem {
private static Set<Class<?>> usefullDirectories = new HashSet<Class<?>>();
public static final int ORIENTATION_NORMAL = 1;
public static final int ORIENTATION_ROTATE_180 = 3;
public static final int ORIENTATION_ROTATE_90 = 6; // rotate 90 cw to right it
public static final int ORIENTATION_ROTATE_270 = 8; // rotate 270 to right it
static {
usefullDirectories.add(ExifIFD0Directory.class);
usefullDirectories.add(ExifSubIFDDirectory.class);
//usefullDirectories.add(BmpHeaderDirectory.class);
//usefullDirectories.add(GifHeaderDirectory.class);
//usefullDirectories.add(JpegDirectory.class);
//usefullDirectories.add(PngDirectory.class);
//usefullDirectories.add(WebpDirectory.class);
usefullDirectories.add(GpsDirectory.class);
usefullDirectories.add(XmpDirectory.class);
}
private int width = -1;
private int height = -1;
private String make = null;
private String model = null;
private String fNumber = null;
private String iso = null;
private String exposureTime = null;
private Date dateOriginal = null;
private GeoLocation location = null;
private int orientation = -1;
MetadataItem(File file) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
setWidth(options.outWidth);
setHeight(options.outHeight);
try {
Metadata metadata = ImageMetadataReader.readMetadata(file);
// TODO: 21/08/16 should I switch to ExifInterface or to any other lib?
for(Directory directory : metadata.getDirectories()) {
if (usefullDirectories.contains(directory.getClass())) {
if (directory.getClass().equals(ExifSubIFDDirectory.class) || directory.getClass().equals(ExifIFD0Directory.class)) {
ExifDirectoryBase d = (ExifDirectoryBase) directory;
if (d.containsTag(ExifDirectoryBase.TAG_MAKE))
setMake(d.getString(ExifDirectoryBase.TAG_MAKE));
if (d.containsTag(ExifDirectoryBase.TAG_MODEL))
setModel(d.getString(ExifDirectoryBase.TAG_MODEL));
if (d.containsTag(ExifDirectoryBase.TAG_ISO_EQUIVALENT))
setIso(d.getString(ExifDirectoryBase.TAG_ISO_EQUIVALENT));
if (d.containsTag(ExifDirectoryBase.TAG_EXPOSURE_TIME) && d.getRational(ExifDirectoryBase.TAG_EXPOSURE_TIME) != null)
setExposureTime(new DecimalFormat("0.000").format(d.getRational(ExifDirectoryBase.TAG_EXPOSURE_TIME)));
if (d.containsTag(ExifDirectoryBase.TAG_FNUMBER))
setfNumber(d.getString(ExifDirectoryBase.TAG_FNUMBER));
if (d.containsTag(ExifDirectoryBase.TAG_DATETIME_ORIGINAL))
setDateOriginal(d.getDate(ExifDirectoryBase.TAG_DATETIME_ORIGINAL));
} else if (directory.getClass().equals(ExifSubIFDDirectory.class)) {
setDateOriginal(((ExifSubIFDDirectory) directory).getDateOriginal(TimeZone.getDefault()));
} else if (directory.getClass().equals(XmpDirectory.class)) {
XmpDirectory d = (XmpDirectory) directory;
if (d.containsTag(XmpDirectory.TAG_DATETIME_ORIGINAL))
setDateOriginal(d.getDate(XmpDirectory.TAG_DATETIME_ORIGINAL));
if (d.containsTag(XmpDirectory.TAG_MAKE))
setMake(d.getString(XmpDirectory.TAG_MAKE));
if (d.containsTag(XmpDirectory.TAG_MODEL))
setModel(d.getString(XmpDirectory.TAG_MODEL));
if (d.containsTag(XmpDirectory.TAG_F_NUMBER))
setfNumber(d.getString(XmpDirectory.TAG_F_NUMBER));
}
else if (directory.getClass().equals(GpsDirectory.class)) {
GpsDirectory d = (GpsDirectory) directory;
setLocation(d.getGeoLocation());
}
}
}
} catch (ImageProcessingException e) {
Log.wtf("asd", "logMainTags: ImageProcessingException", e);
} catch (IOException e) {
Log.wtf("asd", "logMainTags: IOException", e);
}
}
public int getOrientation() {
return orientation;
}
public void setOrientation(int orientation) {
switch (orientation) {
case ORIENTATION_NORMAL: this.orientation = 0;
case ORIENTATION_ROTATE_90: this.orientation = 90;
case ORIENTATION_ROTATE_180: this.orientation = 180;
case ORIENTATION_ROTATE_270: this.orientation = 270;
}
}
Date getDateOriginal() {
return dateOriginal;
}
private void setDateOriginal(Date dateOriginal) {
this.dateOriginal = dateOriginal;
}
public GeoLocation getLocation() {
return location;
}
public void setLocation(GeoLocation location) {
this.location = location;
}
private int getWidth() {
return width;
}
private void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public String getResolution() {
if(width !=-1 && height != -1)
return String.format("%dx%d", getWidth(), getHeight());
return null;
}
String getCameraInfo() {
if (make != null && model != null) {
if (model.contains(make)) return model;
return String.format("%s %s", make, model);
}
return null;
}
String getExifInfo() {
StringBuilder result = new StringBuilder();
String asd;
if((asd = getfNumber()) != null) result.append(asd).append(" ");
if((asd = getExposureTime()) != null) result.append(asd).append(" ");
if((asd = getIso()) != null) result.append(asd).append(" ");
return result.length() == 0 ? null : result.toString();
}
public void setHeight(int height) {
this.height = height;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
private void setModel(String model) {
this.model = model;
}
private String getfNumber() {
if(fNumber != null)
return String.format("f/%s", fNumber);
return null;
}
private void setfNumber(String fNumber) {
this.fNumber = fNumber;
}
private String getIso() {
if(iso != null)
return String.format("ISO-%s", iso);
return null;
}
private void setIso(String iso) {
this.iso = iso;
}
private String getExposureTime() {
if(exposureTime != null)
return String.format("%ss", exposureTime);
return null;
}
private void setExposureTime(String exposureTime) {
this.exposureTime = exposureTime;
}
}