From 29fd4aa661f7e626a1d11558f09e8f7c011efcc2 Mon Sep 17 00:00:00 2001 From: Ruben Brunk Date: Mon, 11 Mar 2013 19:00:12 -0700 Subject: Exif parser modifications. Bug: 8018327 Change-Id: I66a2ec309f9807ac255bbf29d8f5f26de60e89b8 --- src/com/android/gallery3d/data/Exif.java | 44 ++++---------- src/com/android/gallery3d/data/LocalImage.java | 74 ++++++++---------------- src/com/android/gallery3d/data/MediaDetails.java | 74 ++++++++++++------------ 3 files changed, 71 insertions(+), 121 deletions(-) (limited to 'src/com/android/gallery3d/data') diff --git a/src/com/android/gallery3d/data/Exif.java b/src/com/android/gallery3d/data/Exif.java index 30aba7e97..950e7de18 100644 --- a/src/com/android/gallery3d/data/Exif.java +++ b/src/com/android/gallery3d/data/Exif.java @@ -18,55 +18,31 @@ package com.android.gallery3d.data; import android.util.Log; -import com.android.gallery3d.exif.ExifInvalidFormatException; -import com.android.gallery3d.exif.ExifParser; -import com.android.gallery3d.exif.ExifTag; +import com.android.gallery3d.exif.ExifInterface; import java.io.IOException; import java.io.InputStream; public class Exif { - private static final String TAG = "GalleryExif"; + private static final String TAG = "CameraExif"; + // Returns the degrees in clockwise. Values are 0, 90, 180, or 270. public static int getOrientation(InputStream is) { if (is == null) { return 0; } - + ExifInterface exif = new ExifInterface(); try { - ExifParser parser = ExifParser.parse(is, ExifParser.OPTION_IFD_0); - int event = parser.next(); - while (event != ExifParser.EVENT_END) { - if (event == ExifParser.EVENT_NEW_TAG) { - ExifTag tag = parser.getTag(); - if (tag.getTagId() == ExifTag.TAG_ORIENTATION && - tag.hasValue()) { - int orient = (int) tag.getValueAt(0); - switch (orient) { - case ExifTag.Orientation.TOP_LEFT: - return 0; - case ExifTag.Orientation.BOTTOM_LEFT: - return 180; - case ExifTag.Orientation.RIGHT_TOP: - return 90; - case ExifTag.Orientation.RIGHT_BOTTOM: - return 270; - default: - Log.i(TAG, "Unsupported orientation"); - return 0; - } - } - } - event = parser.next(); + exif.readExif(is); + Integer val = exif.getTagIntValue(ExifInterface.TAG_ORIENTATION); + if (val == null) { + return 0; + } else { + return ExifInterface.getRotationForOrientationValue(val.shortValue()); } - Log.i(TAG, "Orientation not found"); - return 0; } catch (IOException e) { Log.w(TAG, "Failed to read EXIF orientation", e); return 0; - } catch (ExifInvalidFormatException e) { - Log.w(TAG, "Failed to read EXIF orientation", e); - return 0; } } } diff --git a/src/com/android/gallery3d/data/LocalImage.java b/src/com/android/gallery3d/data/LocalImage.java index d5fad5483..1ed67ecf4 100644 --- a/src/com/android/gallery3d/data/LocalImage.java +++ b/src/com/android/gallery3d/data/LocalImage.java @@ -23,7 +23,6 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; -import android.media.ExifInterface; import android.net.Uri; import android.os.Build; import android.provider.MediaStore.Images; @@ -37,8 +36,7 @@ import com.android.gallery3d.app.StitchingProgressManager; import com.android.gallery3d.common.ApiHelper; import com.android.gallery3d.common.BitmapUtils; import com.android.gallery3d.common.Utils; -import com.android.gallery3d.exif.ExifInvalidFormatException; -import com.android.gallery3d.exif.ExifModifier; +import com.android.gallery3d.exif.ExifInterface; import com.android.gallery3d.exif.ExifTag; import com.android.gallery3d.util.GalleryUtils; import com.android.gallery3d.util.ThreadPool.Job; @@ -46,6 +44,7 @@ import com.android.gallery3d.util.ThreadPool.JobContext; import com.android.gallery3d.util.UpdateHelper; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel.MapMode; @@ -196,15 +195,15 @@ public class LocalImage extends LocalMediaItem { // try to decode from JPEG EXIF if (type == MediaItem.TYPE_MICROTHUMBNAIL) { - ExifInterface exif = null; - byte [] thumbData = null; + ExifInterface exif = new ExifInterface(); + byte[] thumbData = null; try { - exif = new ExifInterface(mLocalFilePath); - if (exif != null) { - thumbData = exif.getThumbnail(); - } - } catch (Throwable t) { - Log.w(TAG, "fail to get exif thumb", t); + exif.readExif(mLocalFilePath); + thumbData = exif.getThumbnail(); + } catch (FileNotFoundException e) { + Log.w(TAG, "failed to find file to read thumbnail: " + mLocalFilePath); + } catch (IOException e) { + Log.w(TAG, "failed to get thumbnail from: " + mLocalFilePath); } if (thumbData != null) { Bitmap bitmap = DecodeUtils.decodeIfBigEnough( @@ -276,21 +275,6 @@ public class LocalImage extends LocalMediaItem { new String[]{String.valueOf(id)}); } - private static int getExifOrientation(int orientation) { - switch (orientation) { - case 0: - return ExifInterface.ORIENTATION_NORMAL; - case 90: - return ExifInterface.ORIENTATION_ROTATE_90; - case 180: - return ExifInterface.ORIENTATION_ROTATE_180; - case 270: - return ExifInterface.ORIENTATION_ROTATE_270; - default: - throw new AssertionError("invalid: " + orientation); - } - } - @Override public void rotate(int degrees) { GalleryUtils.assertNotInRenderThread(); @@ -300,34 +284,22 @@ public class LocalImage extends LocalMediaItem { if (rotation < 0) rotation += 360; if (mimeType.equalsIgnoreCase("image/jpeg")) { - RandomAccessFile file = null; - try { - // Because most of the images contain the orientation tag, we - // use ExifModifier to modify the tag for better efficiency. - // If the tag doesn't exist, ExifInterface will be used to replace the entire - // header. - file = new RandomAccessFile(filePath, "rw"); - ExifModifier modifier = new ExifModifier( - file.getChannel().map(MapMode.READ_WRITE, 0, file.length())); - ExifTag tag = ExifTag.buildTag(ExifTag.TAG_ORIENTATION); - tag.setValue(getExifOrientation(rotation)); - modifier.modifyTag(tag); - if (!modifier.commit()) { - // Need to change the file size, use ExifInterface instead. - ExifInterface exif = new ExifInterface(filePath); - exif.setAttribute(ExifInterface.TAG_ORIENTATION, - String.valueOf(getExifOrientation(rotation))); - exif.saveAttributes(); - // We need to update the filesize as well + ExifInterface exifInterface = new ExifInterface(); + ExifTag tag = exifInterface.buildTag(ExifInterface.TAG_ORIENTATION, + ExifInterface.getOrientationValueForRotation(rotation)); + if(tag != null) { + exifInterface.setTag(tag); + try { + exifInterface.forceRewriteExif(filePath); fileSize = new File(filePath).length(); values.put(Images.Media.SIZE, fileSize); + } catch (FileNotFoundException e) { + Log.w(TAG, "cannot find file to set exif: " + filePath); + } catch (IOException e) { + Log.w(TAG, "cannot set exif data: " + filePath); } - } catch (IOException e) { - Log.w(TAG, "cannot set exif data: " + filePath); - } catch (ExifInvalidFormatException e) { - Log.w(TAG, "cannot set exif data: " + filePath); - } finally { - Utils.closeSilently(file); + } else { + Log.w(TAG, "Could not build tag: " + ExifInterface.TAG_ORIENTATION); } } diff --git a/src/com/android/gallery3d/data/MediaDetails.java b/src/com/android/gallery3d/data/MediaDetails.java index 662bd141c..cac524b88 100644 --- a/src/com/android/gallery3d/data/MediaDetails.java +++ b/src/com/android/gallery3d/data/MediaDetails.java @@ -18,12 +18,12 @@ package com.android.gallery3d.data; import com.android.gallery3d.R; import com.android.gallery3d.common.Utils; -import com.android.gallery3d.exif.ExifData; -import com.android.gallery3d.exif.ExifInvalidFormatException; -import com.android.gallery3d.exif.ExifReader; +import com.android.gallery3d.exif.ExifInterface; import com.android.gallery3d.exif.ExifTag; +import com.android.gallery3d.exif.Rational; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; @@ -115,11 +115,11 @@ public class MediaDetails implements Iterable> { String value = null; int type = tag.getDataType(); if (type == ExifTag.TYPE_UNSIGNED_RATIONAL || type == ExifTag.TYPE_RATIONAL) { - value = String.valueOf(tag.getRational(0).toDouble()); + value = String.valueOf(tag.getValueAsRational(0).toDouble()); } else if (type == ExifTag.TYPE_ASCII) { - value = tag.getString(); + value = tag.getValueAsString(); } else { - value = String.valueOf(tag.getValueAt(0)); + value = String.valueOf(tag.forceGetValueAsLong(0)); } if (key == MediaDetails.INDEX_FLASH) { MediaDetails.FlashState state = new MediaDetails.FlashState( @@ -132,37 +132,39 @@ public class MediaDetails implements Iterable> { } public static void extractExifInfo(MediaDetails details, String filePath) { - InputStream is = null; + + ExifInterface exif = new ExifInterface(); try { - is = new FileInputStream(filePath); - ExifData data = new ExifReader().read(is); - setExifData(details, data.getTag(ExifTag.TAG_FLASH), MediaDetails.INDEX_FLASH); - setExifData(details, data.getTag(ExifTag.TAG_IMAGE_WIDTH), MediaDetails.INDEX_WIDTH); - setExifData(details, data.getTag(ExifTag.TAG_IMAGE_LENGTH), MediaDetails.INDEX_HEIGHT); - setExifData(details, data.getTag(ExifTag.TAG_MAKE), MediaDetails.INDEX_MAKE); - setExifData(details, data.getTag(ExifTag.TAG_MODEL),MediaDetails.INDEX_MODEL); - setExifData(details, data.getTag(ExifTag.TAG_APERTURE_VALUE), - MediaDetails.INDEX_APERTURE); - setExifData(details, data.getTag(ExifTag.TAG_ISO_SPEED_RATINGS), - MediaDetails.INDEX_ISO); - setExifData(details, data.getTag(ExifTag.TAG_WHITE_BALANCE), - MediaDetails.INDEX_WHITE_BALANCE); - setExifData(details, data.getTag(ExifTag.TAG_EXPOSURE_TIME), - MediaDetails.INDEX_EXPOSURE_TIME); - ExifTag focalTag = data.getTag(ExifTag.TAG_FOCAL_LENGTH); - if (focalTag != null) { - details.addDetail(MediaDetails.INDEX_FOCAL_LENGTH, - focalTag.getRational(0).toDouble()); - details.setUnit(MediaDetails.INDEX_FOCAL_LENGTH, R.string.unit_mm); - } - } catch (IOException ex) { - // ignore it. - Log.w(TAG, "", ex); - } catch (ExifInvalidFormatException ex) { - // ignore it. - Log.w(TAG, "", ex); - } finally { - Utils.closeSilently(is); + exif.readExif(filePath); + } catch (FileNotFoundException e) { + Log.w(TAG, "Could not find file to read exif: " + filePath, e); + } catch (IOException e) { + Log.w(TAG, "Could not read exif from file: " + filePath, e); + } + + setExifData(details, exif.getTag(ExifInterface.TAG_FLASH), + MediaDetails.INDEX_FLASH); + setExifData(details, exif.getTag(ExifInterface.TAG_IMAGE_WIDTH), + MediaDetails.INDEX_WIDTH); + setExifData(details, exif.getTag(ExifInterface.TAG_IMAGE_LENGTH), + MediaDetails.INDEX_HEIGHT); + setExifData(details, exif.getTag(ExifInterface.TAG_MAKE), + MediaDetails.INDEX_MAKE); + setExifData(details, exif.getTag(ExifInterface.TAG_MODEL), + MediaDetails.INDEX_MODEL); + setExifData(details, exif.getTag(ExifInterface.TAG_APERTURE_VALUE), + MediaDetails.INDEX_APERTURE); + setExifData(details, exif.getTag(ExifInterface.TAG_ISO_SPEED_RATINGS), + MediaDetails.INDEX_ISO); + setExifData(details, exif.getTag(ExifInterface.TAG_WHITE_BALANCE), + MediaDetails.INDEX_WHITE_BALANCE); + setExifData(details, exif.getTag(ExifInterface.TAG_EXPOSURE_TIME), + MediaDetails.INDEX_EXPOSURE_TIME); + ExifTag focalTag = exif.getTag(ExifInterface.TAG_FOCAL_LENGTH); + if (focalTag != null) { + details.addDetail(MediaDetails.INDEX_FOCAL_LENGTH, + focalTag.getValueAsRational(0).toDouble()); + details.setUnit(MediaDetails.INDEX_FOCAL_LENGTH, R.string.unit_mm); } } } -- cgit v1.2.3