diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2013-03-11 19:00:12 -0700 |
---|---|---|
committer | Ruben Brunk <rubenbrunk@google.com> | 2013-03-13 18:01:42 -0700 |
commit | 29fd4aa661f7e626a1d11558f09e8f7c011efcc2 (patch) | |
tree | c493ac90f0f3783e2efeea17083164a742cc621f /src/com/android/gallery3d | |
parent | acca4ee0fefe6442b853510b6b360f6cb7ad1bc5 (diff) | |
download | android_packages_apps_Snap-29fd4aa661f7e626a1d11558f09e8f7c011efcc2.tar.gz android_packages_apps_Snap-29fd4aa661f7e626a1d11558f09e8f7c011efcc2.tar.bz2 android_packages_apps_Snap-29fd4aa661f7e626a1d11558f09e8f7c011efcc2.zip |
Exif parser modifications.
Bug: 8018327
Change-Id: I66a2ec309f9807ac255bbf29d8f5f26de60e89b8
Diffstat (limited to 'src/com/android/gallery3d')
-rw-r--r-- | src/com/android/gallery3d/data/Exif.java | 44 | ||||
-rw-r--r-- | src/com/android/gallery3d/data/LocalImage.java | 74 | ||||
-rw-r--r-- | src/com/android/gallery3d/data/MediaDetails.java | 74 | ||||
-rw-r--r-- | src/com/android/gallery3d/filtershow/cache/ImageLoader.java | 50 | ||||
-rw-r--r-- | src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java | 181 |
5 files changed, 177 insertions, 246 deletions
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<Entry<Integer, Object>> { 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<Entry<Integer, Object>> { } 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); } } } diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java index 6cf462269..2c1a847f8 100644 --- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java +++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java @@ -27,7 +27,7 @@ import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; import android.graphics.Matrix; import android.graphics.Rect; -import android.media.ExifInterface; +import android.graphics.Bitmap.CompressFormat; import android.net.Uri; import android.provider.MediaStore; import android.util.Log; @@ -36,9 +36,8 @@ import com.adobe.xmp.XMPException; import com.adobe.xmp.XMPMeta; import com.android.gallery3d.R; import com.android.gallery3d.common.Utils; -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 com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.HistoryAdapter; import com.android.gallery3d.filtershow.imageshow.ImageShow; @@ -48,6 +47,8 @@ import com.android.gallery3d.filtershow.tools.SaveCopyTask; import com.android.gallery3d.util.InterruptableOutputStream; import com.android.gallery3d.util.XmpUtilHelper; +import java.io.ByteArrayInputStream; +import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -79,14 +80,14 @@ public class ImageLoader { public static final String DEFAULT_SAVE_DIRECTORY = "EditedOnlinePhotos"; public static final int DEFAULT_COMPRESS_QUALITY = 95; - public static final int ORI_NORMAL = ExifInterface.ORIENTATION_NORMAL; - public static final int ORI_ROTATE_90 = ExifInterface.ORIENTATION_ROTATE_90; - public static final int ORI_ROTATE_180 = ExifInterface.ORIENTATION_ROTATE_180; - public static final int ORI_ROTATE_270 = ExifInterface.ORIENTATION_ROTATE_270; - public static final int ORI_FLIP_HOR = ExifInterface.ORIENTATION_FLIP_HORIZONTAL; - public static final int ORI_FLIP_VERT = ExifInterface.ORIENTATION_FLIP_VERTICAL; - public static final int ORI_TRANSPOSE = ExifInterface.ORIENTATION_TRANSPOSE; - public static final int ORI_TRANSVERSE = ExifInterface.ORIENTATION_TRANSVERSE; + public static final int ORI_NORMAL = ExifInterface.Orientation.TOP_LEFT; + public static final int ORI_ROTATE_90 = ExifInterface.Orientation.RIGHT_TOP; + public static final int ORI_ROTATE_180 = ExifInterface.Orientation.BOTTOM_LEFT; + public static final int ORI_ROTATE_270 = ExifInterface.Orientation.RIGHT_BOTTOM; + public static final int ORI_FLIP_HOR = ExifInterface.Orientation.TOP_RIGHT; + public static final int ORI_FLIP_VERT = ExifInterface.Orientation.BOTTOM_RIGHT; + public static final int ORI_TRANSPOSE = ExifInterface.Orientation.LEFT_TOP; + public static final int ORI_TRANSVERSE = ExifInterface.Orientation.LEFT_BOTTOM; private static final int BITMAP_LOAD_BACKOUT_ATTEMPTS = 5; private Context mContext = null; @@ -147,26 +148,13 @@ public class ImageLoader { String path = uri.getPath(); int orientation = -1; InputStream is = null; + ExifInterface exif = new ExifInterface(); try { - is = new FileInputStream(path); - 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) { - orientation = (int) tag.getValueAt(0); - break; - } - } - event = parser.next(); - } + exif.readExif(path); + orientation = ExifInterface.getRotationForOrientationValue( + exif.getTagIntValue(ExifInterface.TAG_ORIENTATION).shortValue()); } catch (IOException e) { - e.printStackTrace(); - } catch (ExifInvalidFormatException e) { - e.printStackTrace(); - } finally { - Utils.closeSilently(is); + Log.w(LOGTAG, "Failed to read EXIF orientation", e); } return orientation; } @@ -196,9 +184,9 @@ public class ImageLoader { return -1; } } catch (SQLiteException e) { - return ExifInterface.ORIENTATION_UNDEFINED; + return -1; } catch (IllegalArgumentException e) { - return ExifInterface.ORIENTATION_UNDEFINED; + return -1; } finally { Utils.closeSilently(cursor); } diff --git a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java index b88dbbc47..aa7e70065 100644 --- a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java +++ b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java @@ -21,7 +21,6 @@ import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; -import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.AsyncTask; @@ -31,21 +30,15 @@ import android.provider.MediaStore.Images.ImageColumns; import android.util.Log; import com.android.gallery3d.common.Utils; -import com.android.gallery3d.exif.ExifData; -import com.android.gallery3d.exif.ExifInvalidFormatException; -import com.android.gallery3d.exif.ExifOutputStream; -import com.android.gallery3d.exif.ExifReader; -import com.android.gallery3d.exif.ExifTag; +import com.android.gallery3d.exif.ExifInterface; import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.presets.ImagePreset; import com.android.gallery3d.util.XmpUtilHelper; import java.io.File; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.sql.Date; import java.text.SimpleDateFormat; import java.util.TimeZone; @@ -55,35 +48,7 @@ import java.util.TimeZone; */ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { - private static final String LOGTAG = "SaveCopyTask"; - /** - * Saves the bitmap in the final destination - */ - public static void saveBitmap(Bitmap bitmap, File destination, Object xmp) { - saveBitmap(bitmap, destination, xmp, null); - } - - private static void saveBitmap(Bitmap bitmap, File destination, Object xmp, ExifData exif) { - OutputStream os = null; - try { - os = new FileOutputStream(destination); - if (exif != null) { - ExifOutputStream eos = new ExifOutputStream(os); - eos.setExifData(exif); - bitmap.compress(CompressFormat.JPEG, ImageLoader.DEFAULT_COMPRESS_QUALITY, eos); - } else { - bitmap.compress(CompressFormat.JPEG, ImageLoader.DEFAULT_COMPRESS_QUALITY, os); - } - } catch (FileNotFoundException e) { - Log.v(LOGTAG,"Error in writing "+destination.getAbsolutePath()); - } finally { - Utils.closeSilently(os);; - } - if (xmp != null) { - XmpUtilHelper.writeXMPMeta(destination.getAbsolutePath(), xmp); - } - } /** * Callback for the completed asynchronous task. @@ -128,7 +93,8 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { ImageLoader.DEFAULT_SAVE_DIRECTORY); } // Create the directory if it doesn't exist - if (!saveDirectory.exists()) saveDirectory.mkdirs(); + if (!saveDirectory.exists()) + saveDirectory.mkdirs(); return saveDirectory; } @@ -139,28 +105,59 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { return new File(saveDirectory, filename + ".JPG"); } - private ExifData getExifData(Uri sourceUri) { + public Object getPanoramaXMPData(Uri source, ImagePreset preset) { + Object xmp = null; + if (preset.isPanoramaSafe()) { + InputStream is = null; + try { + is = context.getContentResolver().openInputStream(source); + xmp = XmpUtilHelper.extractXMPMeta(is); + } catch (FileNotFoundException e) { + Log.w(LOGTAG, "Failed to get XMP data from image: ", e); + } finally { + Utils.closeSilently(is); + } + } + return xmp; + } + + public boolean putPanoramaXMPData(File file, Object xmp) { + if (xmp != null) { + return XmpUtilHelper.writeXMPMeta(file.getAbsolutePath(), xmp); + } + return false; + } + + public ExifInterface getExifData(Uri source) { + ExifInterface exif = new ExifInterface(); String mimeType = context.getContentResolver().getType(sourceUri); - if (mimeType != ImageLoader.JPEG_MIME_TYPE) { - return null; + if (mimeType == ImageLoader.JPEG_MIME_TYPE) { + InputStream inStream = null; + try { + inStream = context.getContentResolver().openInputStream(source); + exif.readExif(inStream); + } catch (FileNotFoundException e) { + Log.w(LOGTAG, "Cannot find file: " + source, e); + } catch (IOException e) { + Log.w(LOGTAG, "Cannot read exif for: " + source, e); + } finally { + Utils.closeSilently(inStream); + } } - InputStream is = null; + return exif; + } + + public boolean putExifData(File file, ExifInterface exif, Bitmap image) { + boolean ret = false; try { - is = context.getContentResolver().openInputStream(sourceUri); - ExifReader reader = new ExifReader(); - return reader.read(is); + exif.writeExif(image, file.getAbsolutePath()); + ret = true; } catch (FileNotFoundException e) { - Log.w(LOGTAG, "Failed to find file", e); - return null; - } catch (ExifInvalidFormatException e) { - Log.w(LOGTAG, "Invalid EXIF data", e); - return null; + Log.w(LOGTAG, "File not found: " + file.getAbsolutePath(), e); } catch (IOException e) { - Log.w(LOGTAG, "Failed to read original file", e); - return null; - } finally { - Utils.closeSilently(is); + Log.w(LOGTAG, "Could not write exif: ", e); } + return ret; } /** @@ -173,12 +170,12 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { return null; } ImagePreset preset = params[0]; - InputStream is = null; BitmapFactory.Options options = new BitmapFactory.Options(); + Uri uri = null; boolean noBitmap = true; int num_tries = 0; // Stopgap fix for low-memory devices. - while(noBitmap) { + while (noBitmap) { try { // Try to do bitmap operations, downsample if low-memory Bitmap bitmap = ImageLoader.loadMutableBitmap(context, sourceUri, options); @@ -189,24 +186,23 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { bitmap = preset.applyGeometry(bitmap); bitmap = preset.apply(bitmap); - Object xmp = null; - if (preset.isPanoramaSafe()) { - is = context.getContentResolver().openInputStream(sourceUri); - xmp = XmpUtilHelper.extractXMPMeta(is); - } - ExifData exif = getExifData(sourceUri); - if (exif != null) { - exif.addDateTimeStampTag(ExifTag.TAG_DATE_TIME, System.currentTimeMillis(), - TimeZone.getDefault()); - // Since the image has been modified, set the orientation to normal. - exif.addTag(ExifTag.TAG_ORIENTATION).setValue(ExifTag.Orientation.TOP_LEFT); + Object xmp = getPanoramaXMPData(sourceUri, preset); + ExifInterface exif = getExifData(sourceUri); + + // Set tags + long time = System.currentTimeMillis(); + exif.addDateTimeStampTag(ExifInterface.TAG_DATE_TIME, time, + TimeZone.getDefault()); + exif.setTag(exif.buildTag(ExifInterface.TAG_ORIENTATION, + ExifInterface.Orientation.TOP_LEFT)); + + // If we succeed in writing the bitmap as a jpeg, return a uri. + if (putExifData(this.destinationFile, exif, bitmap)) { + putPanoramaXMPData(this.destinationFile, xmp); + uri = insertContent(context, sourceUri, this.destinationFile, saveFileName, + time); } - saveBitmap(bitmap, this.destinationFile, xmp, exif); - bitmap.recycle(); noBitmap = false; - } catch (FileNotFoundException ex) { - Log.w(LOGTAG, "Failed to save image!", ex); - return null; } catch (java.lang.OutOfMemoryError e) { // Try 5 times before failing for good. if (++num_tries >= 5) { @@ -214,13 +210,9 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { } System.gc(); options.inSampleSize *= 2; - } finally { - Utils.closeSilently(is); } } - Uri uri = insertContent(context, sourceUri, this.destinationFile, saveFileName); return uri; - } @Override @@ -267,16 +259,17 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { /** * Insert the content (saved file) with proper source photo properties. */ - public static Uri insertContent(Context context, Uri sourceUri, File file, String saveFileName) { - long now = System.currentTimeMillis() / 1000; + public static Uri insertContent(Context context, Uri sourceUri, File file, String saveFileName, + long time) { + time /= 1000; final ContentValues values = new ContentValues(); values.put(Images.Media.TITLE, saveFileName); values.put(Images.Media.DISPLAY_NAME, file.getName()); values.put(Images.Media.MIME_TYPE, "image/jpeg"); - values.put(Images.Media.DATE_TAKEN, now); - values.put(Images.Media.DATE_MODIFIED, now); - values.put(Images.Media.DATE_ADDED, now); + values.put(Images.Media.DATE_TAKEN, time); + values.put(Images.Media.DATE_MODIFIED, time); + values.put(Images.Media.DATE_ADDED, time); values.put(Images.Media.ORIENTATION, 0); values.put(Images.Media.DATA, file.getAbsolutePath()); values.put(Images.Media.SIZE, file.length()); @@ -288,20 +281,20 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { querySource(context, sourceUri, projection, new ContentResolverQueryCallback() { - @Override - public void onCursorResult(Cursor cursor) { - values.put(Images.Media.DATE_TAKEN, cursor.getLong(0)); - - double latitude = cursor.getDouble(1); - double longitude = cursor.getDouble(2); - // TODO: Change || to && after the default location issue is - // fixed. - if ((latitude != 0f) || (longitude != 0f)) { - values.put(Images.Media.LATITUDE, latitude); - values.put(Images.Media.LONGITUDE, longitude); - } - } - }); + @Override + public void onCursorResult(Cursor cursor) { + values.put(Images.Media.DATE_TAKEN, cursor.getLong(0)); + + double latitude = cursor.getDouble(1); + double longitude = cursor.getDouble(2); + // TODO: Change || to && after the default location + // issue is fixed. + if ((latitude != 0f) || (longitude != 0f)) { + values.put(Images.Media.LATITUDE, latitude); + values.put(Images.Media.LONGITUDE, longitude); + } + } + }); return context.getContentResolver().insert( Images.Media.EXTERNAL_CONTENT_URI, values); |