blob: dbb65feaf4896f5131bc621b7e77f281ee2920ab [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.gallery3d.data;
import com.android.gallery3d.R;
import com.android.gallery3d.exif.ExifInterface;
import com.android.gallery3d.exif.ExifTag;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.TreeMap;
public class MediaDetails implements Iterable<Entry<Integer, Object>> {
@SuppressWarnings("unused")
private static final String TAG = "MediaDetails";
private TreeMap<Integer, Object> mDetails = new TreeMap<Integer, Object>();
private HashMap<Integer, Integer> mUnits = new HashMap<Integer, Integer>();
public static final int INDEX_TITLE = 1;
public static final int INDEX_DESCRIPTION = 2;
public static final int INDEX_DATETIME = 3;
public static final int INDEX_LOCATION = 4;
public static final int INDEX_WIDTH = 5;
public static final int INDEX_HEIGHT = 6;
public static final int INDEX_ORIENTATION = 7;
public static final int INDEX_DURATION = 8;
public static final int INDEX_MIMETYPE = 9;
public static final int INDEX_SIZE = 10;
// for EXIF
public static final int INDEX_DATETIME_ORIGINAL = 100;
public static final int INDEX_MAKE = 101;
public static final int INDEX_MODEL = 102;
public static final int INDEX_FLASH = 103;
public static final int INDEX_FOCAL_LENGTH = 104;
public static final int INDEX_WHITE_BALANCE = 105;
public static final int INDEX_APERTURE = 106;
public static final int INDEX_SHUTTER_SPEED = 107;
public static final int INDEX_EXPOSURE_TIME = 108;
public static final int INDEX_ISO = 109;
// Put this last because it may be long.
public static final int INDEX_PATH = 200;
public static class FlashState {
private static int FLASH_FIRED_MASK = 1;
private static int FLASH_RETURN_MASK = 2 | 4;
private static int FLASH_MODE_MASK = 8 | 16;
private static int FLASH_FUNCTION_MASK = 32;
private static int FLASH_RED_EYE_MASK = 64;
private int mState;
public FlashState(int state) {
mState = state;
}
public boolean isFlashFired() {
return (mState & FLASH_FIRED_MASK) != 0;
}
}
public void addDetail(int index, Object value) {
mDetails.put(index, value);
}
public Object getDetail(int index) {
return mDetails.get(index);
}
public int size() {
return mDetails.size();
}
@Override
public Iterator<Entry<Integer, Object>> iterator() {
return mDetails.entrySet().iterator();
}
public void setUnit(int index, int unit) {
mUnits.put(index, unit);
}
public boolean hasUnit(int index) {
return mUnits.containsKey(index);
}
public int getUnit(int index) {
return mUnits.get(index);
}
private static void setExifData(MediaDetails details, ExifTag tag,
int key) {
if (tag != null) {
String value = null;
int type = tag.getDataType();
if (type == ExifTag.TYPE_UNSIGNED_RATIONAL || type == ExifTag.TYPE_RATIONAL) {
value = String.valueOf(tag.getValueAsRational(0).toDouble());
} else if (type == ExifTag.TYPE_ASCII) {
value = tag.getValueAsString();
} else {
value = String.valueOf(tag.forceGetValueAsLong(0));
}
if (key == MediaDetails.INDEX_FLASH) {
MediaDetails.FlashState state = new MediaDetails.FlashState(
Integer.valueOf(value.toString()));
details.addDetail(key, state);
} else {
details.addDetail(key, value);
}
}
}
public static void extractExifInfo(MediaDetails details, String filePath) {
ExifInterface exif = new ExifInterface();
try {
exif.readExif(filePath);
} catch (FileNotFoundException e) {
Log.w(TAG, "Could not find file to read exif: " + filePath, e);
} catch (IOException e) {
Log.w(TAG, "Could not read exif from file: " + filePath, e);
}
setExifData(details, exif.getTag(ExifInterface.TAG_FLASH),
MediaDetails.INDEX_FLASH);
setExifData(details, exif.getTag(ExifInterface.TAG_IMAGE_WIDTH),
MediaDetails.INDEX_WIDTH);
setExifData(details, exif.getTag(ExifInterface.TAG_IMAGE_LENGTH),
MediaDetails.INDEX_HEIGHT);
ExifTag recordTag = exif.getTag(ExifInterface.TAG_DATE_TIME_ORIGINAL);
if (recordTag == null) {
recordTag = exif.getTag(ExifInterface.TAG_DATE_TIME_DIGITIZED);
}
if (recordTag == null) {
recordTag = exif.getTag(ExifInterface.TAG_DATE_TIME);
}
setExifData(details, recordTag, MediaDetails.INDEX_DATETIME_ORIGINAL);
setExifData(details, exif.getTag(ExifInterface.TAG_MAKE),
MediaDetails.INDEX_MAKE);
setExifData(details, exif.getTag(ExifInterface.TAG_MODEL),
MediaDetails.INDEX_MODEL);
setExifData(details, exif.getTag(ExifInterface.TAG_APERTURE_VALUE),
MediaDetails.INDEX_APERTURE);
setExifData(details, exif.getTag(ExifInterface.TAG_ISO_SPEED_RATINGS),
MediaDetails.INDEX_ISO);
setExifData(details, exif.getTag(ExifInterface.TAG_WHITE_BALANCE),
MediaDetails.INDEX_WHITE_BALANCE);
setExifData(details, exif.getTag(ExifInterface.TAG_EXPOSURE_TIME),
MediaDetails.INDEX_EXPOSURE_TIME);
ExifTag focalTag = exif.getTag(ExifInterface.TAG_FOCAL_LENGTH);
if (focalTag != null) {
details.addDetail(MediaDetails.INDEX_FOCAL_LENGTH,
focalTag.getValueAsRational(0).toDouble());
details.setUnit(MediaDetails.INDEX_FOCAL_LENGTH, R.string.unit_mm);
}
ExifTag latitudeTag = exif.getTag(ExifInterface.TAG_GPS_LATITUDE);
ExifTag longitudeTag = exif.getTag(ExifInterface.TAG_GPS_LONGITUDE);
if (latitudeTag != null && longitudeTag != null) {
double latitude = latitudeTag.getValueAsRational(0).toDouble();
double longitude = longitudeTag.getValueAsRational(0).toDouble();
details.addDetail(MediaDetails.INDEX_LOCATION, new double[] {latitude, longitude});
}
}
}