OSDN Git Service

merge in klp-release history after reset to klp-dev
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / tools / SaveImage.java
index 9c881d1..bd483d3 100644 (file)
@@ -32,10 +32,10 @@ import android.util.Log;
 import com.android.gallery3d.common.Utils;
 import com.android.gallery3d.exif.ExifInterface;
 import com.android.gallery3d.filtershow.FilterShowActivity;
-import com.android.gallery3d.filtershow.pipeline.CachingPipeline;
 import com.android.gallery3d.filtershow.cache.ImageLoader;
 import com.android.gallery3d.filtershow.filters.FiltersManager;
 import com.android.gallery3d.filtershow.imageshow.MasterImage;
+import com.android.gallery3d.filtershow.pipeline.CachingPipeline;
 import com.android.gallery3d.filtershow.pipeline.ImagePreset;
 import com.android.gallery3d.filtershow.pipeline.ProcessingService;
 import com.android.gallery3d.util.UsageStatistics;
@@ -46,6 +46,7 @@ import java.io.FileNotFoundException;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.sql.Date;
 import java.text.SimpleDateFormat;
 import java.util.TimeZone;
@@ -257,20 +258,29 @@ public class SaveImage {
         return exif;
     }
 
-    public boolean putExifData(File file, ExifInterface exif, Bitmap image) {
+    public boolean putExifData(File file, ExifInterface exif, Bitmap image,
+            int jpegCompressQuality) {
         boolean ret = false;
+        OutputStream s = null;
         try {
-            exif.writeExif(image, file.getAbsolutePath());
+            s = exif.getExifWriterStream(file.getAbsolutePath());
+            image.compress(Bitmap.CompressFormat.JPEG,
+                    (jpegCompressQuality > 0) ? jpegCompressQuality : 1, s);
+            s.flush();
+            s.close();
+            s = null;
             ret = true;
         } catch (FileNotFoundException e) {
             Log.w(LOGTAG, "File not found: " + file.getAbsolutePath(), e);
         } catch (IOException e) {
             Log.w(LOGTAG, "Could not write exif: ", e);
+        } finally {
+            Utils.closeSilently(s);
         }
         return ret;
     }
 
-    private Uri resetToOriginalImageIfNeeded(ImagePreset preset) {
+    private Uri resetToOriginalImageIfNeeded(ImagePreset preset, boolean doAuxBackup) {
         Uri uri = null;
         if (!preset.hasModifications()) {
             // This can happen only when preset has no modification but save
@@ -284,7 +294,7 @@ public class SaveImage {
             if (srcFile != null) {
                 srcFile.renameTo(mDestinationFile);
                 uri = SaveImage.linkNewFileToUri(mContext, mSelectedImageUri,
-                        mDestinationFile, System.currentTimeMillis());
+                        mDestinationFile, System.currentTimeMillis(), doAuxBackup);
             }
         }
         return uri;
@@ -300,9 +310,10 @@ public class SaveImage {
         }
     }
 
-    public Uri processAndSaveImage(ImagePreset preset) {
+    public Uri processAndSaveImage(ImagePreset preset, boolean doAuxBackup,
+                                   int quality, float sizeFactor) {
 
-        Uri uri = resetToOriginalImageIfNeeded(preset);
+        Uri uri = resetToOriginalImageIfNeeded(preset, doAuxBackup);
         if (uri != null) {
             return null;
         }
@@ -316,7 +327,10 @@ public class SaveImage {
         // If necessary, move the source file into the auxiliary directory,
         // newSourceUri is then pointing to the new location.
         // If no file is moved, newSourceUri will be the same as mSourceUri.
-        Uri newSourceUri = moveSrcToAuxIfNeeded(mSourceUri, mDestinationFile);
+        Uri newSourceUri = mSourceUri;
+        if (doAuxBackup) {
+            newSourceUri = moveSrcToAuxIfNeeded(mSourceUri, mDestinationFile);
+        }
 
         // Stopgap fix for low-memory devices.
         while (noBitmap) {
@@ -328,6 +342,12 @@ public class SaveImage {
                 if (bitmap == null) {
                     return null;
                 }
+                if (sizeFactor != 1f) {
+                    // if we have a valid size
+                    int w = (int) (bitmap.getWidth() * sizeFactor);
+                    int h = (int) (bitmap.getHeight() * sizeFactor);
+                    bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
+                }
                 updateProgress();
                 CachingPipeline pipeline = new CachingPipeline(FiltersManager.getManager(),
                         "Saving");
@@ -351,7 +371,7 @@ public class SaveImage {
                 updateProgress();
 
                 // If we succeed in writing the bitmap as a jpeg, return a uri.
-                if (putExifData(mDestinationFile, exif, bitmap)) {
+                if (putExifData(mDestinationFile, exif, bitmap, quality)) {
                     putPanoramaXMPData(mDestinationFile, xmp);
                     // mDestinationFile will save the newSourceUri info in the XMP.
                     XmpPresets.writeFilterXMP(mContext, newSourceUri,
@@ -360,7 +380,7 @@ public class SaveImage {
                     // After this call, mSelectedImageUri will be actually
                     // pointing at the new file mDestinationFile.
                     uri = SaveImage.linkNewFileToUri(mContext, mSelectedImageUri,
-                            mDestinationFile, time);
+                            mDestinationFile, time, doAuxBackup);
                 }
                 updateProgress();
 
@@ -382,7 +402,8 @@ public class SaveImage {
 
     /**
      *  Move the source file to auxiliary directory if needed and return the Uri
-     *  pointing to this new source file.
+     *  pointing to this new source file. If any file error happens, then just
+     *  don't move into the auxiliary directory.
      * @param srcUri Uri to the source image.
      * @param dstFile Providing the destination file info to help to build the
      *  auxiliary directory and new source file's name.
@@ -399,7 +420,10 @@ public class SaveImage {
         // if necessary.
         File auxDiretory = getLocalAuxDirectory(dstFile);
         if (!auxDiretory.exists()) {
-            auxDiretory.mkdirs();
+            boolean success = auxDiretory.mkdirs();
+            if (!success) {
+                return srcUri;
+            }
         }
 
         // Make sure there is a .nomedia file in the auxiliary directory, such
@@ -416,9 +440,23 @@ public class SaveImage {
         // We are using the destination file name such that photos sitting in
         // the auxiliary directory are matching the parent directory.
         File newSrcFile = new File(auxDiretory, dstFile.getName());
+        // Maintain the suffix during move
+        String to = newSrcFile.getName();
+        String from = srcFile.getName();
+        to = to.substring(to.lastIndexOf("."));
+        from = from.substring(from.lastIndexOf("."));
+
+        if (!to.equals(from)) {
+            String name = dstFile.getName();
+            name = name.substring(0, name.lastIndexOf(".")) + from;
+            newSrcFile = new File(auxDiretory, name);
+        }
 
         if (!newSrcFile.exists()) {
-            srcFile.renameTo(newSrcFile);
+            boolean success = srcFile.renameTo(newSrcFile);
+            if (!success) {
+                return srcUri;
+            }
         }
 
         return Uri.fromFile(newSrcFile);
@@ -436,7 +474,7 @@ public class SaveImage {
         String filename = new SimpleDateFormat(TIME_STAMP_NAME).format(new Date(time));
         File saveDirectory = getFinalSaveDirectory(context, sourceUri);
         File file = new File(saveDirectory, filename  + ".JPG");
-        return linkNewFileToUri(context, sourceUri, file, time);
+        return linkNewFileToUri(context, sourceUri, file, time, false);
     }
 
     public static void saveImage(ImagePreset preset, final FilterShowActivity filterShowActivity,
@@ -445,7 +483,7 @@ public class SaveImage {
         Uri sourceImageUri = MasterImage.getImage().getUri();
 
         Intent processIntent = ProcessingService.getSaveIntent(filterShowActivity, preset,
-                destination, selectedImageUri, sourceImageUri);
+                destination, selectedImageUri, sourceImageUri, false, 90, 1f);
 
         filterShowActivity.startService(processIntent);
 
@@ -565,7 +603,7 @@ public class SaveImage {
      * @return the final Uri referring to the <code>file</code>.
      */
     public static Uri linkNewFileToUri(Context context, Uri sourceUri,
-            File file, long time) {
+            File file, long time, boolean deleteOriginal) {
         File oldSelectedFile = getLocalFileFromUri(context, sourceUri);
         final ContentValues values = new ContentValues();
 
@@ -603,7 +641,12 @@ public class SaveImage {
                 });
 
         Uri result = sourceUri;
-        if (oldSelectedFile == null) {
+
+        // In the case of incoming Uri is just a local file Uri (like a cached
+        // file), we can't just update the Uri. We have to create a new Uri.
+        boolean fileUri = isFileUri(sourceUri);
+
+        if (fileUri || oldSelectedFile == null || !deleteOriginal) {
             result = context.getContentResolver().insert(
                     Images.Media.EXTERNAL_CONTENT_URI, values);
         } else {
@@ -612,8 +655,19 @@ public class SaveImage {
                 oldSelectedFile.delete();
             }
         }
-
         return result;
     }
 
+    /**
+     * @param sourceUri
+     * @return true if the sourceUri is a local file Uri.
+     */
+    private static boolean isFileUri(Uri sourceUri) {
+        String scheme = sourceUri.getScheme();
+        if (scheme != null && scheme.equals(ContentResolver.SCHEME_FILE)) {
+            return true;
+        }
+        return false;
+    }
+
 }