diff --git a/src/com/android/ex/photo/util/Exif.java b/src/com/android/ex/photo/util/Exif.java
new file mode 100644
index 0000000..743b896
--- /dev/null
+++ b/src/com/android/ex/photo/util/Exif.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2010 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.ex.photo.util;
+
+import android.util.Log;
+
+public class Exif {
+    private static final String TAG = "CameraExif";
+
+    // Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
+    public static int getOrientation(byte[] jpeg) {
+        if (jpeg == null) {
+            return 0;
+        }
+
+        int offset = 0;
+        int length = 0;
+
+        // ISO/IEC 10918-1:1993(E)
+        while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) {
+            int marker = jpeg[offset] & 0xFF;
+
+            // Check if the marker is a padding.
+            if (marker == 0xFF) {
+                continue;
+            }
+            offset++;
+
+            // Check if the marker is SOI or TEM.
+            if (marker == 0xD8 || marker == 0x01) {
+                continue;
+            }
+            // Check if the marker is EOI or SOS.
+            if (marker == 0xD9 || marker == 0xDA) {
+                break;
+            }
+
+            // Get the length and check if it is reasonable.
+            length = pack(jpeg, offset, 2, false);
+            if (length < 2 || offset + length > jpeg.length) {
+                Log.e(TAG, "Invalid length");
+                return 0;
+            }
+
+            // Break if the marker is EXIF in APP1.
+            if (marker == 0xE1 && length >= 8 &&
+                    pack(jpeg, offset + 2, 4, false) == 0x45786966 &&
+                    pack(jpeg, offset + 6, 2, false) == 0) {
+                offset += 8;
+                length -= 8;
+                break;
+            }
+
+            // Skip other markers.
+            offset += length;
+            length = 0;
+        }
+
+        // JEITA CP-3451 Exif Version 2.2
+        if (length > 8) {
+            // Identify the byte order.
+            int tag = pack(jpeg, offset, 4, false);
+            if (tag != 0x49492A00 && tag != 0x4D4D002A) {
+                Log.e(TAG, "Invalid byte order");
+                return 0;
+            }
+            boolean littleEndian = (tag == 0x49492A00);
+
+            // Get the offset and check if it is reasonable.
+            int count = pack(jpeg, offset + 4, 4, littleEndian) + 2;
+            if (count < 10 || count > length) {
+                Log.e(TAG, "Invalid offset");
+                return 0;
+            }
+            offset += count;
+            length -= count;
+
+            // Get the count and go through all the elements.
+            count = pack(jpeg, offset - 2, 2, littleEndian);
+            while (count-- > 0 && length >= 12) {
+                // Get the tag and check if it is orientation.
+                tag = pack(jpeg, offset, 2, littleEndian);
+                if (tag == 0x0112) {
+                    // We do not really care about type and count, do we?
+                    int orientation = pack(jpeg, offset + 8, 2, littleEndian);
+                    switch (orientation) {
+                        case 1:
+                            return 0;
+                        case 3:
+                            return 180;
+                        case 6:
+                            return 90;
+                        case 8:
+                            return 270;
+                    }
+                    Log.i(TAG, "Unsupported orientation");
+                    return 0;
+                }
+                offset += 12;
+                length -= 12;
+            }
+        }
+
+        Log.i(TAG, "Orientation not found");
+        return 0;
+    }
+
+    private static int pack(byte[] bytes, int offset, int length,
+            boolean littleEndian) {
+        int step = 1;
+        if (littleEndian) {
+            offset += length - 1;
+            step = -1;
+        }
+
+        int value = 0;
+        while (length-- > 0) {
+            value = (value << 8) | (bytes[offset] & 0xFF);
+            offset += step;
+        }
+        return value;
+    }
+}
diff --git a/src/com/android/ex/photo/util/ImageUtils.java b/src/com/android/ex/photo/util/ImageUtils.java
index d852d65..7fe971a 100644
--- a/src/com/android/ex/photo/util/ImageUtils.java
+++ b/src/com/android/ex/photo/util/ImageUtils.java
@@ -1,175 +1,211 @@
-/*
- * Copyright (C) 2011 Google Inc.
- * Licensed to 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.ex.photo.util;
-
-import android.content.ContentResolver;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Build;
-import android.util.Log;
-
-import com.android.ex.photo.PhotoViewActivity;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Image utilities
- */
-public class ImageUtils {
-    // Logging
-    private static final String TAG = "ImageUtils";
-
-    /** Minimum class memory class to use full-res photos */
-    private final static long MIN_NORMAL_CLASS = 32;
-    /** Minimum class memory class to use small photos */
-    private final static long MIN_SMALL_CLASS = 24;
-
-    public static enum ImageSize {
-        EXTRA_SMALL,
-        SMALL,
-        NORMAL,
-    }
-
-    public static final ImageSize sUseImageSize;
-    static {
-        // On HC and beyond, assume devices are more capable
-        if (Build.VERSION.SDK_INT >= 11) {
-            sUseImageSize = ImageSize.NORMAL;
-        } else {
-            if (PhotoViewActivity.sMemoryClass >= MIN_NORMAL_CLASS) {
-                // We have plenty of memory; use full sized photos
-                sUseImageSize = ImageSize.NORMAL;
-            } else if (PhotoViewActivity.sMemoryClass >= MIN_SMALL_CLASS) {
-                // We have slight less memory; use smaller sized photos
-                sUseImageSize = ImageSize.SMALL;
-            } else {
-                // We have little memory; use very small sized photos
-                sUseImageSize = ImageSize.EXTRA_SMALL;
-            }
-        }
-    }
-
-    /**
-     * @return true if the MimeType type is image
-     */
-    public static boolean isImageMimeType(String mimeType) {
-        return mimeType != null && mimeType.startsWith("image/");
-    }
-
-    /**
-     * Create a bitmap from a local URI
-     *
-     * @param resolver The ContentResolver
-     * @param uri The local URI
-     * @param maxSize The maximum size (either width or height)
-     *
-     * @return The new bitmap or null
-     */
-    public static Bitmap createLocalBitmap(ContentResolver resolver, Uri uri, int maxSize) {
-        InputStream inputStream = null;
-        try {
-            final BitmapFactory.Options opts = new BitmapFactory.Options();
-            final Point bounds = getImageBounds(resolver, uri);
-
-            inputStream = resolver.openInputStream(uri);
-            opts.inSampleSize = Math.max(bounds.x / maxSize, bounds.y / maxSize);
-
-            final Bitmap decodedBitmap = decodeStream(inputStream, null, opts);
-
-            // Correct thumbnail orientation as necessary
+/*
+ * Copyright (C) 2011 Google Inc.
+ * Licensed to 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.ex.photo.util;
+
+import android.content.ContentResolver;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Build;
+import android.util.DisplayMetrics;
+import android.util.Log;
+
+import com.android.ex.photo.PhotoViewActivity;
+import com.android.ex.photo.util.Exif;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Image utilities
+ */
+public class ImageUtils {
+    // Logging
+    private static final String TAG = "ImageUtils";
+
+    /** Minimum class memory class to use full-res photos */
+    private final static long MIN_NORMAL_CLASS = 32;
+    /** Minimum class memory class to use small photos */
+    private final static long MIN_SMALL_CLASS = 24;
+
+    public static enum ImageSize {
+        EXTRA_SMALL,
+        SMALL,
+        NORMAL,
+    }
+
+    public static final ImageSize sUseImageSize;
+    static {
+        // On HC and beyond, assume devices are more capable
+        if (Build.VERSION.SDK_INT >= 11) {
+            sUseImageSize = ImageSize.NORMAL;
+        } else {
+            if (PhotoViewActivity.sMemoryClass >= MIN_NORMAL_CLASS) {
+                // We have plenty of memory; use full sized photos
+                sUseImageSize = ImageSize.NORMAL;
+            } else if (PhotoViewActivity.sMemoryClass >= MIN_SMALL_CLASS) {
+                // We have slight less memory; use smaller sized photos
+                sUseImageSize = ImageSize.SMALL;
+            } else {
+                // We have little memory; use very small sized photos
+                sUseImageSize = ImageSize.EXTRA_SMALL;
+            }
+        }
+    }
+
+    /**
+     * @return true if the MimeType type is image
+     */
+    public static boolean isImageMimeType(String mimeType) {
+        return mimeType != null && mimeType.startsWith("image/");
+    }
+
+    /**
+     * Create a bitmap from a local URI
+     *
+     * @param resolver The ContentResolver
+     * @param uri The local URI
+     * @param maxSize The maximum size (either width or height)
+     *
+     * @return The new bitmap or null
+     */
+    public static Bitmap createLocalBitmap(ContentResolver resolver, Uri uri, int maxSize) {
+        InputStream inputStream = null;
+        try {
+            final BitmapFactory.Options opts = new BitmapFactory.Options();
+            final Point bounds = getImageBounds(resolver, uri);
+
+            inputStream = resolver.openInputStream(uri);
+            opts.inSampleSize = Math.max(bounds.x / maxSize, bounds.y / maxSize);
+
+            final Bitmap decodedBitmap = decodeStream(inputStream, null, opts);
+
+            // Correct thumbnail orientation as necessary
             // TODO: Fix rotation if it's actually a problem
             //return rotateBitmap(resolver, uri, decodedBitmap);
             return decodedBitmap;
-
-        } catch (FileNotFoundException exception) {
-            // Do nothing - the photo will appear to be missing
-        } catch (IOException exception) {
-            // Do nothing - the photo will appear to be missing
+
+        } catch (FileNotFoundException exception) {
+            // Do nothing - the photo will appear to be missing
+        } catch (IOException exception) {
+            // Do nothing - the photo will appear to be missing
         } catch (IllegalArgumentException exception) {
             // Do nothing - the photo will appear to be missing
-        } finally {
-            try {
-                if (inputStream != null) {
-                    inputStream.close();
-                }
-            } catch (IOException ignore) {
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Wrapper around {@link BitmapFactory#decodeStream(InputStream, Rect,
-     * BitmapFactory.Options)} that returns {@code null} on {@link
-     * OutOfMemoryError}.
-     *
-     * @param is The input stream that holds the raw data to be decoded into a
-     *           bitmap.
-     * @param outPadding If not null, return the padding rect for the bitmap if
-     *                   it exists, otherwise set padding to [-1,-1,-1,-1]. If
-     *                   no bitmap is returned (null) then padding is
-     *                   unchanged.
-     * @param opts null-ok; Options that control downsampling and whether the
-     *             image should be completely decoded, or just is size returned.
-     * @return The decoded bitmap, or null if the image data could not be
-     *         decoded, or, if opts is non-null, if opts requested only the
-     *         size be returned (in opts.outWidth and opts.outHeight)
-     */
-    public static Bitmap decodeStream(InputStream is, Rect outPadding, BitmapFactory.Options opts) {
-        try {
-            return BitmapFactory.decodeStream(is, outPadding, opts);
-        } catch (OutOfMemoryError oome) {
-            Log.e(TAG, "ImageUtils#decodeStream(InputStream, Rect, Options) threw an OOME", oome);
-            return null;
-        }
-    }
-
-    /**
-     * Gets the image bounds
-     *
-     * @param resolver The ContentResolver
-     * @param uri The uri
-     *
-     * @return The image bounds
-     */
-    private static Point getImageBounds(ContentResolver resolver, Uri uri)
-            throws IOException {
-        final BitmapFactory.Options opts = new BitmapFactory.Options();
-        InputStream inputStream = null;
-
-        try {
-            opts.inJustDecodeBounds = true;
-            inputStream = resolver.openInputStream(uri);
-            decodeStream(inputStream, null, opts);
-
-            return new Point(opts.outWidth, opts.outHeight);
-        } finally {
-            try {
-                if (inputStream != null) {
-                    inputStream.close();
-                }
-            } catch (IOException ignore) {
-            }
-        }
-    }
-}
+        } finally {
+            try {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            } catch (IOException ignore) {
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Wrapper around {@link BitmapFactory#decodeStream(InputStream, Rect,
+     * BitmapFactory.Options)} that returns {@code null} on {@link
+     * OutOfMemoryError}.
+     *
+     * @param is The input stream that holds the raw data to be decoded into a
+     *           bitmap.
+     * @param outPadding If not null, return the padding rect for the bitmap if
+     *                   it exists, otherwise set padding to [-1,-1,-1,-1]. If
+     *                   no bitmap is returned (null) then padding is
+     *                   unchanged.
+     * @param opts null-ok; Options that control downsampling and whether the
+     *             image should be completely decoded, or just is size returned.
+     * @return The decoded bitmap, or null if the image data could not be
+     *         decoded, or, if opts is non-null, if opts requested only the
+     *         size be returned (in opts.outWidth and opts.outHeight)
+     */
+    public static Bitmap decodeStream(InputStream is, Rect outPadding, BitmapFactory.Options opts) {
+        ByteArrayOutputStream out = null;
+        try {
+            out = new ByteArrayOutputStream();
+            final byte[] buffer = new byte[4096];
+            int n = is.read(buffer);
+            while (n >= 0) {
+                out.write(buffer, 0, n);
+                n = is.read(buffer);
+            }
+            final byte[] bitmapBytes = out.toByteArray();
+
+            // Determine the orientation for this image
+            final int orientation = Exif.getOrientation(bitmapBytes);
+            final Bitmap originalBitmap =
+                    BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length, opts);
+
+            if (originalBitmap != null && orientation != 0) {
+                final Matrix matrix = new Matrix();
+                matrix.postRotate(orientation);
+                return Bitmap.createBitmap(originalBitmap, 0, 0, originalBitmap.getWidth(),
+                        originalBitmap.getHeight(), matrix, true);
+            }
+            return originalBitmap;
+        } catch (OutOfMemoryError oome) {
+            Log.e(TAG, "ImageUtils#decodeStream(InputStream, Rect, Options) threw an OOME", oome);
+            return null;
+        } catch (IOException ioe) {
+            Log.e(TAG, "ImageUtils#decodeStream(InputStream, Rect, Options) threw an IOE", ioe);
+            return null;
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    // Do nothing
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the image bounds
+     *
+     * @param resolver The ContentResolver
+     * @param uri The uri
+     *
+     * @return The image bounds
+     */
+    private static Point getImageBounds(ContentResolver resolver, Uri uri)
+            throws IOException {
+        final BitmapFactory.Options opts = new BitmapFactory.Options();
+        InputStream inputStream = null;
+
+        try {
+            opts.inJustDecodeBounds = true;
+            inputStream = resolver.openInputStream(uri);
+            decodeStream(inputStream, null, opts);
+
+            return new Point(opts.outWidth, opts.outHeight);
+        } finally {
+            try {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            } catch (IOException ignore) {
+            }
+        }
+    }
+}
