summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEarl Ou <shunhsingou@google.com>2012-08-16 10:41:57 +0800
committerEarl Ou <shunhsingou@google.com>2012-08-27 11:05:39 +0800
commitfd745274358be4afdc0876985b108c2a20ef6b06 (patch)
treead51320e782c76f76db9912717626746cc9359c7
parent0b6bca8513ae49dacbfdbd9c800ba9f542b6b68b (diff)
downloadandroid_packages_apps_Snap-fd745274358be4afdc0876985b108c2a20ef6b06.tar.gz
android_packages_apps_Snap-fd745274358be4afdc0876985b108c2a20ef6b06.tar.bz2
android_packages_apps_Snap-fd745274358be4afdc0876985b108c2a20ef6b06.zip
Read thumbnail into ExifData
Change-Id: Iccc0fbbda1734795ff431075bade700ca5076a08
-rw-r--r--src/com/android/gallery3d/exif/ExifData.java57
-rw-r--r--src/com/android/gallery3d/exif/ExifReader.java14
-rw-r--r--tests/src/com/android/gallery3d/exif/ExifReaderTest.java58
3 files changed, 126 insertions, 3 deletions
diff --git a/src/com/android/gallery3d/exif/ExifData.java b/src/com/android/gallery3d/exif/ExifData.java
index 712698ef4..5b0e3d8e4 100644
--- a/src/com/android/gallery3d/exif/ExifData.java
+++ b/src/com/android/gallery3d/exif/ExifData.java
@@ -15,6 +15,9 @@
*/
package com.android.gallery3d.exif;
+
+import java.util.ArrayList;
+
/**
* This class stores the EXIF header in IFDs according to the JPEG specification.
* It is the result produced by {@link ExifReader}.
@@ -23,6 +26,8 @@ package com.android.gallery3d.exif;
*/
public class ExifData {
private final IfdData[] mIfdDatas = new IfdData[IfdId.TYPE_IFD_COUNT];
+ private byte[] mThumbnail;
+ private ArrayList<byte[]> mStripBytes = new ArrayList<byte[]>();
/**
* Gets the IFD data of the specified IFD.
@@ -44,4 +49,56 @@ public class ExifData {
public void addIfdData(IfdData data) {
mIfdDatas[data.getId()] = data;
}
+
+ /**
+ * Gets the compressed thumbnail. Returns null if there is no compressed thumbnail.
+ *
+ * @see #hasCompressedThumbnail()
+ */
+ public byte[] getCompressedThumbnail() {
+ return mThumbnail;
+ }
+
+ /**
+ * Sets the compressed thumbnail.
+ */
+ public void setCompressedThumbnail(byte[] thumbnail) {
+ mThumbnail = thumbnail;
+ }
+
+ /**
+ * Returns true it this header contains a compressed thumbnail.
+ */
+ public boolean hasCompressedThumbnail() {
+ return mThumbnail != null;
+ }
+
+ /**
+ * Adds an uncompressed strip.
+ */
+ public void setStripBytes(int index, byte[] strip) {
+ if (index < mStripBytes.size()) {
+ mStripBytes.set(index, strip);
+ } else {
+ for (int i = mStripBytes.size(); i < index; i++) {
+ mStripBytes.add(null);
+ }
+ mStripBytes.add(strip);
+ }
+ }
+
+ /**
+ * Gets the strip count
+ */
+ public int getStripCount() {
+ return mStripBytes.size();
+ }
+
+ /**
+ * Gets the strip at the specified index.
+ * @exceptions #IndexOutOfBoundException
+ */
+ public byte[] getStrip(int index) {
+ return mStripBytes.get(index);
+ }
} \ No newline at end of file
diff --git a/src/com/android/gallery3d/exif/ExifReader.java b/src/com/android/gallery3d/exif/ExifReader.java
index 125b6c65e..c259461f2 100644
--- a/src/com/android/gallery3d/exif/ExifReader.java
+++ b/src/com/android/gallery3d/exif/ExifReader.java
@@ -24,11 +24,11 @@ import java.io.InputStream;
*/
public class ExifReader {
/**
- * Parse the inputStream and return all Exif data.
+ * Parses the inputStream and and returns the EXIF data in an {@link ExifData}.
* @throws ExifInvalidFormatException
* @throws IOException
*/
- public ExifData getExifData(InputStream inputStream) throws ExifInvalidFormatException,
+ public ExifData read(InputStream inputStream) throws ExifInvalidFormatException,
IOException {
ExifParser parser = ExifParser.parse(inputStream);
ExifData exifData = new ExifData();
@@ -56,6 +56,16 @@ public class ExifReader {
}
exifData.getIfdData(tag.getIfd()).setTag(tag);
break;
+ case ExifParser.EVENT_COMPRESSED_IMAGE:
+ byte buf[] = new byte[parser.getCompressedImageSize()];
+ parser.read(buf);
+ exifData.setCompressedThumbnail(buf);
+ break;
+ case ExifParser.EVENT_UNCOMPRESSED_STRIP:
+ buf = new byte[parser.getStripSize()];
+ parser.read(buf);
+ exifData.setStripBytes(parser.getStripIndex(), buf);
+ break;
}
event = parser.next();
}
diff --git a/tests/src/com/android/gallery3d/exif/ExifReaderTest.java b/tests/src/com/android/gallery3d/exif/ExifReaderTest.java
index c0c2f9f81..67e695682 100644
--- a/tests/src/com/android/gallery3d/exif/ExifReaderTest.java
+++ b/tests/src/com/android/gallery3d/exif/ExifReaderTest.java
@@ -17,6 +17,7 @@
package com.android.gallery3d.exif;
import android.content.res.XmlResourceParser;
+import android.graphics.BitmapFactory;
import android.test.InstrumentationTestCase;
import java.io.IOException;
@@ -56,12 +57,67 @@ public class ExifReaderTest extends InstrumentationTestCase {
public void testRead() throws ExifInvalidFormatException, IOException {
ExifReader reader = new ExifReader();
- ExifData exifData = reader.getExifData(mImageInputStream);
+ ExifData exifData = reader.read(mImageInputStream);
checkIfd(exifData.getIfdData(IfdId.TYPE_IFD_0), mIfd0Value);
checkIfd(exifData.getIfdData(IfdId.TYPE_IFD_1), mIfd1Value);
checkIfd(exifData.getIfdData(IfdId.TYPE_IFD_EXIF), mExifIfdValue);
checkIfd(exifData.getIfdData(IfdId.TYPE_IFD_INTEROPERABILITY),
mInteroperabilityIfdValue);
+ checkThumbnail(exifData);
+ }
+
+ private void checkThumbnail(ExifData exifData) {
+ IfdData ifd1 = exifData.getIfdData(IfdId.TYPE_IFD_1);
+ if (ifd1 != null) {
+ if (ifd1.getTag(ExifTag.TIFF_TAG.TAG_COMPRESSION).getUnsignedShort() ==
+ ExifTag.TIFF_TAG.COMPRESSION_JPEG) {
+ assertTrue(exifData.hasCompressedThumbnail());
+ byte[] thumbnail = exifData.getCompressedThumbnail();
+ assertTrue(BitmapFactory.decodeByteArray(thumbnail, 0, thumbnail.length) != null);
+ } else {
+ // Try to check the strip count with the formula provided by EXIF spec.
+ int planarType = ExifTag.TIFF_TAG.PLANAR_CONFIGURATION_CHUNKY;
+ ExifTag planarTag = ifd1.getTag(ExifTag.TIFF_TAG.TAG_PLANAR_CONFIGURATION);
+ if (planarTag != null) {
+ planarType = planarTag.getUnsignedShort();
+ }
+
+ ExifTag heightTag = ifd1.getTag(ExifTag.TIFF_TAG.TAG_IMAGE_HEIGHT);
+ ExifTag rowPerStripTag = ifd1.getTag(ExifTag.TIFF_TAG.TAG_ROWS_PER_STRIP);
+
+ int imageLength = getUnsignedIntOrShort(heightTag);
+ int rowsPerStrip = getUnsignedIntOrShort(rowPerStripTag);
+ int stripCount = ifd1.getTag(
+ ExifTag.TIFF_TAG.TAG_STRIP_OFFSETS).getComponentCount();
+
+ if (planarType == ExifTag.TIFF_TAG.PLANAR_CONFIGURATION_CHUNKY) {
+ assertTrue(stripCount == (imageLength + rowsPerStrip - 1) / rowsPerStrip);
+ } else {
+ ExifTag samplePerPixelTag = ifd1.getTag(ExifTag.TIFF_TAG.TAG_SAMPLES_PER_PIXEL);
+ int samplePerPixel = samplePerPixelTag.getUnsignedShort();
+ assertTrue(stripCount ==
+ (imageLength + rowsPerStrip - 1) / rowsPerStrip * samplePerPixel);
+ }
+
+ for (int i = 0; i < stripCount; i++) {
+ ExifTag byteCountTag = ifd1.getTag(ExifTag.TIFF_TAG.TAG_STRIP_BYTE_COUNTS);
+ if (byteCountTag.getDataType() == ExifTag.TYPE_UNSIGNED_SHORT) {
+ assertEquals(byteCountTag.getUnsignedShort(i), exifData.getStrip(i).length);
+ } else {
+ assertEquals(
+ byteCountTag.getUnsignedInt(i), exifData.getStrip(i).length);
+ }
+ }
+ }
+ }
+ }
+
+ private int getUnsignedIntOrShort(ExifTag tag) {
+ if (tag.getDataType() == ExifTag.TYPE_UNSIGNED_SHORT) {
+ return tag.getUnsignedShort();
+ } else {
+ return (int) tag.getUnsignedInt();
+ }
}
private void checkIfd(IfdData ifd, HashMap<Short, String> ifdValue) {