OSDN Git Service

Move ExifInterface to android.media package.
authorrepo sync <raychen@google.com>
Mon, 6 Jul 2009 07:05:23 +0000 (15:05 +0800)
committerRay Chen <raychen@google.com>
Thu, 9 Jul 2009 03:40:34 +0000 (11:40 +0800)
src/com/android/camera/ExifInterface.java [deleted file]
src/com/android/camera/MenuHelper.java
src/com/android/camera/gallery/BaseImageList.java
src/com/android/camera/gallery/Image.java

diff --git a/src/com/android/camera/ExifInterface.java b/src/com/android/camera/ExifInterface.java
deleted file mode 100644 (file)
index a19dee5..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2007 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.camera;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Wrapper for native Exif library
- */
-public class ExifInterface {
-
-    private final String mFilename;
-
-    // Constants used for the Orientation Exif tag.
-    public static final int ORIENTATION_UNDEFINED = 0;
-    public static final int ORIENTATION_NORMAL = 1;
-
-    // Constants used for white balance
-    public static final int WHITEBALANCE_AUTO = 0;
-    public static final int WHITEBALANCE_MANUAL = 1;
-
-    // left right reversed mirror
-    public static final int ORIENTATION_FLIP_HORIZONTAL = 2;
-    public static final int ORIENTATION_ROTATE_180 = 3;
-
-    // upside down mirror
-    public static final int ORIENTATION_FLIP_VERTICAL = 4;
-
-    // flipped about top-left <--> bottom-right axis
-    public static final int ORIENTATION_TRANSPOSE = 5;
-
-    // rotate 90 cw to right it
-    public static final int ORIENTATION_ROTATE_90 = 6;
-
-    // flipped about top-right <--> bottom-left axis
-    public static final int ORIENTATION_TRANSVERSE = 7;
-
-    // rotate 270 to right it
-    public static final int ORIENTATION_ROTATE_270 = 8;
-
-    // The Exif tag names
-    public static final String TAG_ORIENTATION = "Orientation";
-
-    static final String TAG_DATE_TIME_ORIGINAL = "DateTimeOriginal";
-    static final String TAG_MAKE = "Make";
-    static final String TAG_MODEL = "Model";
-    static final String TAG_FLASH = "Flash";
-    static final String TAG_IMAGE_WIDTH = "ImageWidth";
-    static final String TAG_IMAGE_LENGTH = "ImageLength";
-
-    static final String TAG_GPS_LATITUDE = "GPSLatitude";
-    static final String TAG_GPS_LONGITUDE = "GPSLongitude";
-
-    static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
-    static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
-    static final String TAG_WHITE_BALANCE = "WhiteBalance";
-
-    private boolean mSavedAttributes = false;
-    private boolean mHasThumbnail = false;
-    private HashMap<String, String> mCachedAttributes = null;
-
-    static {
-        System.loadLibrary("exif");
-    }
-
-    public ExifInterface(String fileName) {
-        mFilename = fileName;
-    }
-
-    /**
-     * Given a HashMap of Exif tags and associated values, an Exif section in
-     * the JPG file is created and loaded with the tag data. saveAttributes()
-     * is expensive because it involves copying all the JPG data from one file
-     * to another and deleting the old file and renaming the other. It's best
-     * to collect all the attributes to write and make a single call rather
-     * than multiple calls for each attribute. You must call "commitChanges()"
-     * at some point to commit the changes.
-     */
-    public void saveAttributes(HashMap<String, String> attributes) {
-        // format of string passed to native C code:
-        // "attrCnt attr1=valueLen value1attr2=value2Len value2..."
-        // example:
-        // "4 attrPtr ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO"
-        StringBuilder sb = new StringBuilder();
-        int size = attributes.size();
-        if (attributes.containsKey("hasThumbnail")) {
-            --size;
-        }
-        sb.append(size + " ");
-        for (Map.Entry<String, String> iter : attributes.entrySet()) {
-            String key = iter.getKey();
-            if (key.equals("hasThumbnail")) {
-                // this is a fake attribute not saved as an exif tag
-                continue;
-            }
-            String val = iter.getValue();
-            sb.append(key + "=");
-            sb.append(val.length() + " ");
-            sb.append(val);
-        }
-        String s = sb.toString();
-        saveAttributesNative(mFilename, s);
-        commitChangesNative(mFilename);
-        mSavedAttributes = true;
-    }
-
-    /**
-     * Returns a HashMap loaded with the Exif attributes of the file. The key
-     * is the standard tag name and the value is the tag's value: e.g.
-     * Model -> Nikon. Numeric values are returned as strings.
-     */
-    public HashMap<String, String> getAttributes() {
-        if (mCachedAttributes != null) {
-            return mCachedAttributes;
-        }
-        // format of string passed from native C code:
-        // "attrCnt attr1=valueLen value1attr2=value2Len value2..."
-        // example:
-        // "4 attrPtr ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO"
-        mCachedAttributes = new HashMap<String, String>();
-
-        String attrStr = getAttributesNative(mFilename);
-
-        // get count
-        int ptr = attrStr.indexOf(' ');
-        int count = Integer.parseInt(attrStr.substring(0, ptr));
-        // skip past the space between item count and the rest of the attributes
-        ++ptr;
-
-        for (int i = 0; i < count; i++) {
-            // extract the attribute name
-            int equalPos = attrStr.indexOf('=', ptr);
-            String attrName = attrStr.substring(ptr, equalPos);
-            ptr = equalPos + 1;     // skip past =
-
-            // extract the attribute value length
-            int lenPos = attrStr.indexOf(' ', ptr);
-            int attrLen = Integer.parseInt(attrStr.substring(ptr, lenPos));
-            ptr = lenPos + 1;       // skip pas the space
-
-            // extract the attribute value
-            String attrValue = attrStr.substring(ptr, ptr + attrLen);
-            ptr += attrLen;
-
-            if (attrName.equals("hasThumbnail")) {
-                mHasThumbnail = attrValue.equalsIgnoreCase("true");
-            } else {
-                mCachedAttributes.put(attrName, attrValue);
-            }
-        }
-        return mCachedAttributes;
-    }
-
-    /**
-     * Given a numerical white balance value, return a
-     * human-readable string describing it.
-     */
-    public static String whiteBalanceToString(int whitebalance) {
-        switch (whitebalance) {
-            case WHITEBALANCE_AUTO:
-                return "Auto";
-            case WHITEBALANCE_MANUAL:
-                return "Manual";
-            default:
-                return "";
-        }
-    }
-
-    /**
-     * Given a numerical orientation, return a human-readable string describing
-     * the orientation.
-     */
-    public static String orientationToString(int orientation) {
-        // TODO: this function needs to be localized and use string resource ids
-        // rather than strings
-        String orientationString;
-        switch (orientation) {
-            case ORIENTATION_NORMAL:
-                orientationString = "Normal";
-                break;
-            case ORIENTATION_FLIP_HORIZONTAL:
-                orientationString = "Flipped horizontal";
-                break;
-            case ORIENTATION_ROTATE_180:
-                orientationString = "Rotated 180 degrees";
-                break;
-            case ORIENTATION_FLIP_VERTICAL:
-                orientationString = "Upside down mirror";
-                break;
-            case ORIENTATION_TRANSPOSE:
-                orientationString = "Transposed";
-                break;
-            case ORIENTATION_ROTATE_90:
-                orientationString = "Rotated 90 degrees";
-                break;
-            case ORIENTATION_TRANSVERSE:
-                orientationString = "Transversed";
-                break;
-            case ORIENTATION_ROTATE_270:
-                orientationString = "Rotated 270 degrees";
-                break;
-            default:
-                orientationString = "Undefined";
-                break;
-        }
-        return orientationString;
-    }
-
-    /**
-     * Copies the thumbnail data out of the filename and puts it in the Exif
-     * data associated with the file used to create this object. You must call
-     * "commitChanges()" at some point to commit the changes.
-     */
-    public boolean appendThumbnail(String thumbnailFileName) {
-        if (!mSavedAttributes) {
-            throw new RuntimeException("Must call saveAttributes "
-                    + "before calling appendThumbnail");
-        }
-        mHasThumbnail = appendThumbnailNative(mFilename, thumbnailFileName);
-        return mHasThumbnail;
-    }
-
-    public boolean hasThumbnail() {
-        if (!mSavedAttributes) {
-            getAttributes();
-        }
-        return mHasThumbnail;
-    }
-
-    public byte[] getThumbnail() {
-        return getThumbnailNative(mFilename);
-    }
-
-    public static float convertRationalLatLonToFloat(
-            String rationalString, String ref) {
-        try {
-            String [] parts = rationalString.split(",");
-
-            String [] pair;
-            pair = parts[0].split("/");
-            int degrees = (int) (Float.parseFloat(pair[0].trim())
-                    / Float.parseFloat(pair[1].trim()));
-
-            pair = parts[1].split("/");
-            int minutes = (int) ((Float.parseFloat(pair[0].trim())
-                    / Float.parseFloat(pair[1].trim())));
-
-            pair = parts[2].split("/");
-            float seconds = Float.parseFloat(pair[0].trim())
-                    / Float.parseFloat(pair[1].trim());
-
-            float result = degrees + (minutes / 60F) + (seconds / (60F * 60F));
-            if ((ref.equals("S") || ref.equals("W"))) {
-                return -result;
-            }
-            return result;
-        } catch (RuntimeException ex) {
-            // if for whatever reason we can't parse the lat long then return
-            // null
-            return 0f;
-        }
-    }
-
-    public static String convertRationalLatLonToDecimalString(
-            String rationalString, String ref, boolean usePositiveNegative) {
-            float result = convertRationalLatLonToFloat(rationalString, ref);
-
-            String preliminaryResult = String.valueOf(result);
-            if (usePositiveNegative) {
-                String neg = (ref.equals("S") || ref.equals("E")) ? "-" : "";
-                return neg + preliminaryResult;
-            } else {
-                return preliminaryResult + String.valueOf((char) 186) + " "
-                        + ref;
-            }
-    }
-
-    public static String makeLatLongString(double d) {
-        d = Math.abs(d);
-
-        int degrees = (int) d;
-
-        double remainder = d - degrees;
-        int minutes = (int) (remainder * 60D);
-        // really seconds * 1000
-        int seconds = (int) (((remainder * 60D) - minutes) * 60D * 1000D);
-
-        String retVal = degrees + "/1," + minutes + "/1," + seconds + "/1000";
-        return retVal;
-    }
-
-    public static String makeLatStringRef(double lat) {
-        return lat >= 0D ? "N" : "S";
-    }
-
-    public static String makeLonStringRef(double lon) {
-        return lon >= 0D ? "W" : "E";
-    }
-
-    private native boolean appendThumbnailNative(String fileName,
-            String thumbnailFileName);
-
-    private native void saveAttributesNative(String fileName,
-            String compressedAttributes);
-
-    private native String getAttributesNative(String fileName);
-
-    private native void commitChangesNative(String fileName);
-
-    private native byte[] getThumbnailNative(String fileName);
-}
index 604ef5d..193f0ed 100644 (file)
@@ -27,6 +27,7 @@ import android.content.Intent;
 import android.content.DialogInterface.OnClickListener;
 import android.location.Address;
 import android.location.Geocoder;
+import android.media.ExifInterface;
 import android.media.MediaMetadataRetriever;
 import android.net.Uri;
 import android.os.Environment;
@@ -162,32 +163,9 @@ public class MenuHelper {
         d.findViewById(rowId).setVisibility(View.GONE);
     }
 
-    private static float[] getLatLng(HashMap<String, String> exifData) {
-        if (exifData == null) {
-            return null;
-        }
-
-        String latValue = exifData.get(ExifInterface.TAG_GPS_LATITUDE);
-        String latRef = exifData.get(ExifInterface.TAG_GPS_LATITUDE_REF);
-        String lngValue = exifData.get(ExifInterface.TAG_GPS_LONGITUDE);
-        String lngRef = exifData.get(ExifInterface.TAG_GPS_LONGITUDE_REF);
-        float[] latlng = null;
-
-        if (latValue != null && latRef != null
-                && lngValue != null && lngRef != null) {
-            latlng = new float[2];
-            latlng[0] = ExifInterface.convertRationalLatLonToFloat(
-                    latValue, latRef);
-            latlng[1] = ExifInterface.convertRationalLatLonToFloat(
-                    lngValue, lngRef);
-        }
-
-        return latlng;
-    }
-
     private static void setLatLngDetails(View d, Activity context,
             HashMap<String, String> exifData) {
-        float[] latlng = getLatLng(exifData);
+        float[] latlng = ExifInterface.getLatLng(exifData);
         if (latlng != null) {
             setDetailsValue(d, String.valueOf(latlng[0]),
                     R.id.details_latitude_value);
@@ -240,12 +218,7 @@ public class MenuHelper {
             return null;
         }
 
-        ExifInterface exif = new ExifInterface(image.getDataPath());
-        HashMap<String, String> exifData = null;
-        if (exif != null) {
-            exifData = exif.getAttributes();
-        }
-        return exifData;
+        return ExifInterface.loadExifData(image.getDataPath());
     }
     // Called when "Show on Maps" is clicked.
     // Displays image location on Google Maps for further operations.
@@ -257,7 +230,7 @@ public class MenuHelper {
                 if (image == null) {
                     return;
                 }
-                float[] latlng = getLatLng(getExifData(image));
+                float[] latlng = ExifInterface.getLatLng(getExifData(image));
                 if (latlng == null) {
                     handler.post(new Runnable() {
                         public void run() {
@@ -809,7 +782,7 @@ public class MenuHelper {
 
                 list = ImageManager.isVideo(image) ? enableList : disableList;
                 list.addAll(requiresVideoItems);
-                
+
                 for (MenuItem item : enableList) {
                     item.setVisible(true);
                     item.setEnabled(true);
index 97bf1e2..b49acd1 100644 (file)
@@ -16,7 +16,6 @@
 
 package com.android.camera.gallery;
 
-import com.android.camera.ExifInterface;
 import com.android.camera.ImageManager;
 import com.android.camera.Util;
 
@@ -26,6 +25,7 @@ import android.content.ContentValues;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.Parcel;
 import android.provider.BaseColumns;
@@ -200,10 +200,7 @@ public abstract class BaseImageList implements IImageList {
     private Bitmap createThumbnailFromEXIF(String filePath, long id) {
         if (filePath == null) return null;
 
-        byte [] thumbData = null;
-        synchronized (ExifInterface.class) {
-            thumbData = (new ExifInterface(filePath)).getThumbnail();
-        }
+        byte [] thumbData = ExifInterface.getExifThumbnail(filePath);
         if (thumbData == null) return null;
 
         // Sniff the size of the EXIF thumbnail before decoding it. Photos
index cb4c90b..4eba5b3 100644 (file)
 
 package com.android.camera.gallery;
 
+import com.android.camera.BitmapManager;
+import com.android.camera.Util;
+
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
 import android.provider.BaseColumns;
@@ -29,10 +33,6 @@ import android.provider.MediaStore.Images.ImageColumns;
 import android.provider.MediaStore.Images.Thumbnails;
 import android.util.Log;
 
-import com.android.camera.BitmapManager;
-import com.android.camera.ExifInterface;
-import com.android.camera.Util;
-
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.HashMap;
@@ -46,7 +46,6 @@ public class Image extends BaseImage implements IImage {
 
     private HashMap<String, String> mExifData;
 
-    private ExifInterface mExif;
     private int mRotation;
 
     public Image(BaseImageList container, ContentResolver cr,
@@ -189,15 +188,12 @@ public class Image extends BaseImage implements IImage {
     }
 
     private void loadExifData() {
-        mExif = new ExifInterface(mDataPath);
-        if (mExifData == null) {
-            mExifData = mExif.getAttributes();
-        }
+        mExifData = ExifInterface.loadExifData(mDataPath);
     }
 
     private void saveExifData() {
-        if (mExif != null && mExifData != null) {
-            mExif.saveAttributes(mExifData);
+        if (mExifData != null) {
+            ExifInterface.saveExifData(mDataPath, mExifData);
         }
     }