Home | History | Annotate | Download | only in data
      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