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 23 import java.io.IOException; 24 import java.util.HashMap; 25 import java.util.Iterator; 26 import java.util.Map.Entry; 27 import java.util.TreeMap; 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 FlashState(int state)69 public FlashState(int state) { 70 mState = state; 71 } 72 isFlashFired()73 public boolean isFlashFired() { 74 return (mState & FLASH_FIRED_MASK) != 0; 75 } 76 } 77 addDetail(int index, Object value)78 public void addDetail(int index, Object value) { 79 mDetails.put(index, value); 80 } 81 getDetail(int index)82 public Object getDetail(int index) { 83 return mDetails.get(index); 84 } 85 size()86 public int size() { 87 return mDetails.size(); 88 } 89 iterator()90 public Iterator<Entry<Integer, Object>> iterator() { 91 return mDetails.entrySet().iterator(); 92 } 93 setUnit(int index, int unit)94 public void setUnit(int index, int unit) { 95 mUnits.put(index, unit); 96 } 97 hasUnit(int index)98 public boolean hasUnit(int index) { 99 return mUnits.containsKey(index); 100 } 101 getUnit(int index)102 public int getUnit(int index) { 103 return mUnits.get(index); 104 } 105 setExifData(MediaDetails details, ExifInterface exif, String tag, int key)106 private static void setExifData(MediaDetails details, ExifInterface exif, String tag, 107 int key) { 108 String value = exif.getAttribute(tag); 109 if (value != null) { 110 if (key == MediaDetails.INDEX_FLASH) { 111 MediaDetails.FlashState state = new MediaDetails.FlashState( 112 Integer.valueOf(value.toString())); 113 details.addDetail(key, state); 114 } else { 115 details.addDetail(key, value); 116 } 117 } 118 } 119 extractExifInfo(MediaDetails details, String filePath)120 public static void extractExifInfo(MediaDetails details, String filePath) { 121 try { 122 ExifInterface exif = new ExifInterface(filePath); 123 setExifData(details, exif, ExifInterface.TAG_FLASH, MediaDetails.INDEX_FLASH); 124 setExifData(details, exif, ExifInterface.TAG_IMAGE_WIDTH, MediaDetails.INDEX_WIDTH); 125 setExifData(details, exif, ExifInterface.TAG_IMAGE_LENGTH, 126 MediaDetails.INDEX_HEIGHT); 127 setExifData(details, exif, ExifInterface.TAG_MAKE, MediaDetails.INDEX_MAKE); 128 setExifData(details, exif, ExifInterface.TAG_MODEL, MediaDetails.INDEX_MODEL); 129 setExifData(details, exif, ExifInterface.TAG_APERTURE, MediaDetails.INDEX_APERTURE); 130 setExifData(details, exif, ExifInterface.TAG_ISO, MediaDetails.INDEX_ISO); 131 setExifData(details, exif, ExifInterface.TAG_WHITE_BALANCE, 132 MediaDetails.INDEX_WHITE_BALANCE); 133 setExifData(details, exif, ExifInterface.TAG_EXPOSURE_TIME, 134 MediaDetails.INDEX_EXPOSURE_TIME); 135 136 double data = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, 0); 137 if (data != 0f) { 138 details.addDetail(MediaDetails.INDEX_FOCAL_LENGTH, data); 139 details.setUnit(MediaDetails.INDEX_FOCAL_LENGTH, R.string.unit_mm); 140 } 141 } catch (IOException ex) { 142 // ignore it. 143 Log.w(TAG, "", ex); 144 } 145 } 146 } 147