From 91833f3d909c5b01dc590289c1a8dab9e145318a Mon Sep 17 00:00:00 2001 From: Earl Ou Date: Wed, 7 Nov 2012 15:28:48 +0800 Subject: use ExifParser to parse the orientaion Change-Id: I47171c028cbc1f94b7de5d067de0636a9e241fbb --- src/com/android/gallery3d/data/Exif.java | 161 +++++++------------------------ 1 file changed, 36 insertions(+), 125 deletions(-) diff --git a/src/com/android/gallery3d/data/Exif.java b/src/com/android/gallery3d/data/Exif.java index ba5862a86..4d1fc9453 100644 --- a/src/com/android/gallery3d/data/Exif.java +++ b/src/com/android/gallery3d/data/Exif.java @@ -18,144 +18,55 @@ 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 java.io.IOException; import java.io.InputStream; public class Exif { - private static final String TAG = "CameraExif"; + private static final String TAG = "GalleryExif"; public static int getOrientation(InputStream is) { if (is == null) { return 0; } - byte[] buf = new byte[8]; - int length = 0; - - // ISO/IEC 10918-1:1993(E) - while (read(is, buf, 2) && (buf[0] & 0xFF) == 0xFF) { - int marker = buf[1] & 0xFF; - - // Check if the marker is a padding. - if (marker == 0xFF) { - continue; - } - - // 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) { - return 0; - } - - // Get the length and check if it is reasonable. - if (!read(is, buf, 2)) { - return 0; - } - length = pack(buf, 0, 2, false); - if (length < 2) { - Log.e(TAG, "Invalid length"); - return 0; - } - length -= 2; - - // Break if the marker is EXIF in APP1. - if (marker == 0xE1 && length >= 6) { - if (!read(is, buf, 6)) return 0; - length -= 6; - if (pack(buf, 0, 4, false) == 0x45786966 && - pack(buf, 4, 2, false) == 0) { - break; - } - } - - // Skip other markers. - try { - is.skip(length); - } catch (IOException ex) { - return 0; - } - length = 0; - } - - // JEITA CP-3451 Exif Version 2.2 - if (length > 8) { - int offset = 0; - byte[] jpeg = new byte[length]; - if (!read(is, jpeg, length)) { - return 0; - } - - // 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; + 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 = tag.getUnsignedShort(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; + } } - Log.i(TAG, "Unsupported orientation"); - return 0; } - offset += 12; - length -= 12; + event = parser.next(); } - } - - 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; - } - - private static boolean read(InputStream is, byte[] buf, int length) { - try { - return is.read(buf, 0, length) == length; - } catch (IOException ex) { - return false; + 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; } } } -- cgit v1.2.3