1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.gallery3d.data; 18 19 import android.media.ExifInterface; 20 21 import com.android.gallery3d.R; 22 import com.android.gallery3d.common.ExifTags; 23 24 import java.io.IOException; 25 import java.util.HashMap; 26 import java.util.Iterator; 27 import java.util.Map.Entry; 28 import java.util.TreeMap; 29 30 public class MediaDetails implements Iterable<Entry<Integer, Object>> { 31 @SuppressWarnings("unused") 32 private static final String TAG = "MediaDetails"; 33 34 private TreeMap<Integer, Object> mDetails = new TreeMap<Integer, Object>(); 35 private HashMap<Integer, Integer> mUnits = new HashMap<Integer, Integer>(); 36 37 public static final int INDEX_TITLE = 1; 38 public static final int INDEX_DESCRIPTION = 2; 39 public static final int INDEX_DATETIME = 3; 40 public static final int INDEX_LOCATION = 4; 41 public static final int INDEX_WIDTH = 5; 42 public static final int INDEX_HEIGHT = 6; 43 public static final int INDEX_ORIENTATION = 7; 44 public static final int INDEX_DURATION = 8; 45 public static final int INDEX_MIMETYPE = 9; 46 public static final int INDEX_SIZE = 10; 47 48 // for EXIF 49 public static final int INDEX_MAKE = 100; 50 public static final int INDEX_MODEL = 101; 51 public static final int INDEX_FLASH = 102; 52 public static final int INDEX_FOCAL_LENGTH = 103; 53 public static final int INDEX_WHITE_BALANCE = 104; 54 public static final int INDEX_APERTURE = 105; 55 public static final int INDEX_SHUTTER_SPEED = 106; 56 public static final int INDEX_EXPOSURE_TIME = 107; 57 public static final int INDEX_ISO = 108; 58 59 // Put this last because it may be long. 60 public static final int INDEX_PATH = 200; 61 62 public static class FlashState { 63 private static int FLASH_FIRED_MASK = 1; 64 private static int FLASH_RETURN_MASK = 2 | 4; 65 private static int FLASH_MODE_MASK = 8 | 16; 66 private static int FLASH_FUNCTION_MASK = 32; 67 private static int FLASH_RED_EYE_MASK = 64; 68 private int mState; 69 FlashState(int state)70 public FlashState(int state) { 71 mState = state; 72 } 73 isFlashFired()74 public boolean isFlashFired() { 75 return (mState & FLASH_FIRED_MASK) != 0; 76 } 77 } 78 addDetail(int index, Object value)79 public void addDetail(int index, Object value) { 80 mDetails.put(index, value); 81 } 82 getDetail(int index)83 public Object getDetail(int index) { 84 return mDetails.get(index); 85 } 86 size()87 public int size() { 88 return mDetails.size(); 89 } 90 91 @Override iterator()92 public Iterator<Entry<Integer, Object>> iterator() { 93 return mDetails.entrySet().iterator(); 94 } 95 setUnit(int index, int unit)96 public void setUnit(int index, int unit) { 97 mUnits.put(index, unit); 98 } 99 hasUnit(int index)100 public boolean hasUnit(int index) { 101 return mUnits.containsKey(index); 102 } 103 getUnit(int index)104 public int getUnit(int index) { 105 return mUnits.get(index); 106 } 107 setExifData(MediaDetails details, ExifInterface exif, String tag, int key)108 private static void setExifData(MediaDetails details, ExifInterface exif, String tag, 109 int key) { 110 String value = exif.getAttribute(tag); 111 if (value != null) { 112 if (key == MediaDetails.INDEX_FLASH) { 113 MediaDetails.FlashState state = new MediaDetails.FlashState( 114 Integer.valueOf(value.toString())); 115 details.addDetail(key, state); 116 } else { 117 details.addDetail(key, value); 118 } 119 } 120 } 121 extractExifInfo(MediaDetails details, String filePath)122 public static void extractExifInfo(MediaDetails details, String filePath) { 123 try { 124 ExifInterface exif = new ExifInterface(filePath); 125 setExifData(details, exif, ExifInterface.TAG_FLASH, MediaDetails.INDEX_FLASH); 126 setExifData(details, exif, ExifInterface.TAG_IMAGE_WIDTH, MediaDetails.INDEX_WIDTH); 127 setExifData(details, exif, ExifInterface.TAG_IMAGE_LENGTH, 128 MediaDetails.INDEX_HEIGHT); 129 setExifData(details, exif, ExifInterface.TAG_MAKE, MediaDetails.INDEX_MAKE); 130 setExifData(details, exif, ExifInterface.TAG_MODEL, MediaDetails.INDEX_MODEL); 131 setExifData(details, exif, ExifTags.TAG_APERTURE, MediaDetails.INDEX_APERTURE); 132 setExifData(details, exif, ExifTags.TAG_ISO, MediaDetails.INDEX_ISO); 133 setExifData(details, exif, ExifInterface.TAG_WHITE_BALANCE, 134 MediaDetails.INDEX_WHITE_BALANCE); 135 setExifData(details, exif, ExifTags.TAG_EXPOSURE_TIME, 136 MediaDetails.INDEX_EXPOSURE_TIME); 137 138 double data = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, 0); 139 if (data != 0f) { 140 details.addDetail(MediaDetails.INDEX_FOCAL_LENGTH, data); 141 details.setUnit(MediaDetails.INDEX_FOCAL_LENGTH, R.string.unit_mm); 142 } 143 } catch (IOException ex) { 144 // ignore it. 145 Log.w(TAG, "", ex); 146 } 147 } 148 } 149