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 com.android.gallery3d.R; 20 21 import android.media.ExifInterface; 22 23 import java.io.IOException; 24 import java.util.HashMap; 25 import java.util.Iterator; 26 import java.util.TreeMap; 27 import java.util.Map.Entry; 28 29 public class MediaDetails implements Iterable<Entry<Integer, Object>> { 30 @SuppressWarnings("unused") 31 private static final String TAG = "MediaDetails"; 32 33 private TreeMap<Integer, Object> mDetails = new TreeMap<Integer, Object>(); 34 private HashMap<Integer, Integer> mUnits = new HashMap<Integer, Integer>(); 35 36 public static final int INDEX_TITLE = 1; 37 public static final int INDEX_DESCRIPTION = 2; 38 public static final int INDEX_DATETIME = 3; 39 public static final int INDEX_LOCATION = 4; 40 public static final int INDEX_WIDTH = 5; 41 public static final int INDEX_HEIGHT = 6; 42 public static final int INDEX_ORIENTATION = 7; 43 public static final int INDEX_DURATION = 8; 44 public static final int INDEX_MIMETYPE = 9; 45 public static final int INDEX_SIZE = 10; 46 47 // for EXIF 48 public static final int INDEX_MAKE = 100; 49 public static final int INDEX_MODEL = 101; 50 public static final int INDEX_FLASH = 102; 51 public static final int INDEX_FOCAL_LENGTH = 103; 52 public static final int INDEX_WHITE_BALANCE = 104; 53 public static final int INDEX_APERTURE = 105; 54 public static final int INDEX_SHUTTER_SPEED = 106; 55 public static final int INDEX_EXPOSURE_TIME = 107; 56 public static final int INDEX_ISO = 108; 57 58 // Put this last because it may be long. 59 public static final int INDEX_PATH = 200; 60 61 public static class FlashState { 62 private static int FLASH_FIRED_MASK = 1; 63 private static int FLASH_RETURN_MASK = 2 | 4; 64 private static int FLASH_MODE_MASK = 8 | 16; 65 private static int FLASH_FUNCTION_MASK = 32; 66 private static int FLASH_RED_EYE_MASK = 64; 67 private int mState; 68 69 public FlashState(int state) { 70 mState = state; 71 } 72 73 public boolean isFlashFired() { 74 return (mState & FLASH_FIRED_MASK) != 0; 75 } 76 77 public int getFlashReturn() { 78 return (mState & FLASH_RETURN_MASK) >> 1; 79 } 80 81 public int getFlashMode() { 82 return (mState & FLASH_MODE_MASK) >> 3; 83 } 84 85 public boolean isFlashPresent() { 86 return (mState & FLASH_FUNCTION_MASK) != 0; 87 } 88 89 public boolean isRedEyeModePresent() { 90 return (mState & FLASH_RED_EYE_MASK) != 0; 91 } 92 } 93 94 public void addDetail(int index, Object value) { 95 mDetails.put(index, value); 96 } 97 98 public Object getDetail(int index) { 99 return mDetails.get(index); 100 } 101 102 public int size() { 103 return mDetails.size(); 104 } 105 106 public Iterator<Entry<Integer, Object>> iterator() { 107 return mDetails.entrySet().iterator(); 108 } 109 110 public void setUnit(int index, int unit) { 111 mUnits.put(index, unit); 112 } 113 114 public boolean hasUnit(int index) { 115 return mUnits.containsKey(index); 116 } 117 118 public int getUnit(int index) { 119 return mUnits.get(index); 120 } 121 122 private static void setExifData(MediaDetails details, ExifInterface exif, String tag, 123 int key) { 124 String value = exif.getAttribute(tag); 125 if (value != null) { 126 if (key == MediaDetails.INDEX_FLASH) { 127 MediaDetails.FlashState state = new MediaDetails.FlashState( 128 Integer.valueOf(value.toString())); 129 details.addDetail(key, state); 130 } else { 131 details.addDetail(key, value); 132 } 133 } 134 } 135 136 public static void extractExifInfo(MediaDetails details, String filePath) { 137 try { 138 ExifInterface exif = new ExifInterface(filePath); 139 setExifData(details, exif, ExifInterface.TAG_FLASH, MediaDetails.INDEX_FLASH); 140 setExifData(details, exif, ExifInterface.TAG_IMAGE_WIDTH, MediaDetails.INDEX_WIDTH); 141 setExifData(details, exif, ExifInterface.TAG_IMAGE_LENGTH, 142 MediaDetails.INDEX_HEIGHT); 143 setExifData(details, exif, ExifInterface.TAG_MAKE, MediaDetails.INDEX_MAKE); 144 setExifData(details, exif, ExifInterface.TAG_MODEL, MediaDetails.INDEX_MODEL); 145 setExifData(details, exif, ExifInterface.TAG_APERTURE, MediaDetails.INDEX_APERTURE); 146 setExifData(details, exif, ExifInterface.TAG_ISO, MediaDetails.INDEX_ISO); 147 setExifData(details, exif, ExifInterface.TAG_WHITE_BALANCE, 148 MediaDetails.INDEX_WHITE_BALANCE); 149 setExifData(details, exif, ExifInterface.TAG_EXPOSURE_TIME, 150 MediaDetails.INDEX_EXPOSURE_TIME); 151 152 double data = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, 0); 153 if (data != 0f) { 154 details.addDetail(MediaDetails.INDEX_FOCAL_LENGTH, data); 155 details.setUnit(MediaDetails.INDEX_FOCAL_LENGTH, R.string.unit_mm); 156 } 157 } catch (IOException ex) { 158 // ignore it. 159 Log.w(TAG, "", ex); 160 } 161 } 162 } 163