summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gallerycommon/src/com/android/gallery3d/exif/ExifParser.java6
-rw-r--r--tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java24
-rw-r--r--tests/src/com/android/gallery3d/exif/ExifReaderTest.java109
3 files changed, 94 insertions, 45 deletions
diff --git a/gallerycommon/src/com/android/gallery3d/exif/ExifParser.java b/gallerycommon/src/com/android/gallery3d/exif/ExifParser.java
index 36e3b44..a6bbda0 100644
--- a/gallerycommon/src/com/android/gallery3d/exif/ExifParser.java
+++ b/gallerycommon/src/com/android/gallery3d/exif/ExifParser.java
@@ -450,6 +450,12 @@ public class ExifParser {
*/
public int getCompressedImageSize() {
if (mJpegSizeTag == null) return 0;
+
+ // Some invalid image use short type tag
+ if (mJpegSizeTag.getDataType() == ExifTag.TYPE_UNSIGNED_SHORT) {
+ return mJpegSizeTag.getUnsignedShort(0);
+ }
+
// Cast unsigned int to int since the thumbnail is always smaller
// than the size of APP1 (65536)
return (int) mJpegSizeTag.getUnsignedLong(0);
diff --git a/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java b/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java
index 52ae9f3..8c98fa0 100644
--- a/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java
+++ b/tests/src/com/android/gallery3d/exif/ExifOutputStreamTest.java
@@ -28,6 +28,15 @@ import java.io.IOException;
import java.io.InputStream;
public class ExifOutputStreamTest extends ExifXmlDataTestCase {
+
+ private File mTmpFile;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mTmpFile = File.createTempFile("exif_test", ".jpg");
+ }
+
public ExifOutputStreamTest(int imgRes, int xmlRes) {
super(imgRes, xmlRes);
}
@@ -37,7 +46,6 @@ public class ExifOutputStreamTest extends ExifXmlDataTestCase {
}
public void testExifOutputStream() throws Exception {
- File file = File.createTempFile("exif_test", ".jpg");
InputStream imageInputStream = null;
InputStream exifInputStream = null;
FileInputStream reDecodeInputStream = null;
@@ -50,23 +58,26 @@ public class ExifOutputStreamTest extends ExifXmlDataTestCase {
// Read the image data
Bitmap bmp = BitmapFactory.decodeStream(imageInputStream);
+ // The image is invalid
+ if (bmp == null) return;
+
// Read exif data
ExifData exifData = new ExifReader().read(exifInputStream);
// Encode the image with the exif data
- FileOutputStream outputStream = new FileOutputStream(file);
+ FileOutputStream outputStream = new FileOutputStream(mTmpFile);
ExifOutputStream exifOutputStream = new ExifOutputStream(outputStream);
exifOutputStream.setExifData(exifData);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, exifOutputStream);
exifOutputStream.close();
// Re-decode the temp file and check the data.
- reDecodeInputStream = new FileInputStream(file);
+ reDecodeInputStream = new FileInputStream(mTmpFile);
Bitmap decodedBmp = BitmapFactory.decodeStream(reDecodeInputStream);
assertNotNull(getImageTitle(), decodedBmp);
// Re-parse the temp file the check EXIF tag
- reParseInputStream = new FileInputStream(file);
+ reParseInputStream = new FileInputStream(mTmpFile);
ExifData reExifData = new ExifReader().read(reParseInputStream);
assertEquals(getImageTitle(), exifData, reExifData);
} finally {
@@ -90,4 +101,9 @@ public class ExifOutputStreamTest extends ExifXmlDataTestCase {
bos.flush();
return bos.toByteArray();
}
+
+ @Override
+ public void tearDown() {
+ mTmpFile.delete();
+ }
}
diff --git a/tests/src/com/android/gallery3d/exif/ExifReaderTest.java b/tests/src/com/android/gallery3d/exif/ExifReaderTest.java
index 45a9242..374d5b0 100644
--- a/tests/src/com/android/gallery3d/exif/ExifReaderTest.java
+++ b/tests/src/com/android/gallery3d/exif/ExifReaderTest.java
@@ -24,6 +24,14 @@ import java.util.Map;
public class ExifReaderTest extends ExifXmlDataTestCase {
private static final String TAG = "ExifReaderTest";
+ private List<Map<Short, List<String>>> mGroundTruth;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mGroundTruth = ExifXmlReader.readXml(getXmlParser());
+ }
+
public ExifReaderTest(int imgRes, int xmlRes) {
super(imgRes, xmlRes);
}
@@ -36,9 +44,8 @@ public class ExifReaderTest extends ExifXmlDataTestCase {
try {
ExifReader reader = new ExifReader();
ExifData exifData = reader.read(getImageInputStream());
- List<Map<Short, List<String>>> groundTruth = ExifXmlReader.readXml(getXmlParser());
for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) {
- checkIfd(exifData.getIfdData(i), groundTruth.get(i));
+ checkIfd(exifData.getIfdData(i), mGroundTruth.get(i));
}
checkThumbnail(exifData);
} catch (Exception e) {
@@ -47,50 +54,70 @@ public class ExifReaderTest extends ExifXmlDataTestCase {
}
private void checkThumbnail(ExifData exifData) {
+ Map<Short, List<String>> ifd1Truth = mGroundTruth.get(IfdId.TYPE_IFD_1);
+
+ List<String> typeTagValue = ifd1Truth.get(ExifTag.TAG_COMPRESSION);
+ if (typeTagValue == null) return;
+
IfdData ifd1 = exifData.getIfdData(IfdId.TYPE_IFD_1);
- if (ifd1 != null) {
- int type = ifd1.getTag(ExifTag.TAG_COMPRESSION).getUnsignedShort(0);
- if (type == ExifTag.Compression.JPEG) {
- assertTrue(getImageTitle(), exifData.hasCompressedThumbnail());
- byte[] thumbnail = exifData.getCompressedThumbnail();
- assertTrue(getImageTitle(),
- BitmapFactory.decodeByteArray(thumbnail, 0, thumbnail.length) != null);
- } else if (type == ExifTag.Compression.UNCOMPRESSION) {
- // Try to check the strip count with the formula provided by EXIF spec.
- int planarType = ExifTag.PlanarConfiguration.CHUNKY;
- ExifTag planarTag = ifd1.getTag(ExifTag.TAG_PLANAR_CONFIGURATION);
- if (planarTag != null) {
- planarType = planarTag.getUnsignedShort(0);
- }
+ if (ifd1 == null) fail(getImageTitle() + ": failed to find IFD1");
- ExifTag heightTag = ifd1.getTag(ExifTag.TAG_IMAGE_LENGTH);
- ExifTag rowPerStripTag = ifd1.getTag(ExifTag.TAG_ROWS_PER_STRIP);
+ String typeTagTruth = typeTagValue.get(0);
- int imageLength = getUnsignedIntOrShort(heightTag);
- int rowsPerStrip = getUnsignedIntOrShort(rowPerStripTag);
- int stripCount = ifd1.getTag(
- ExifTag.TAG_STRIP_OFFSETS).getComponentCount();
+ ExifTag typeTag = ifd1.getTag(ExifTag.TAG_COMPRESSION);
+ int type = typeTag.getUnsignedShort(0);
- if (planarType == ExifTag.PlanarConfiguration.CHUNKY) {
- assertTrue(getImageTitle(),
- stripCount == (imageLength + rowsPerStrip - 1) / rowsPerStrip);
- } else {
- ExifTag samplePerPixelTag = ifd1.getTag(ExifTag.TAG_SAMPLES_PER_PIXEL);
- int samplePerPixel = samplePerPixelTag.getUnsignedShort(0);
- assertTrue(getImageTitle(),
- stripCount ==
- (imageLength + rowsPerStrip - 1) / rowsPerStrip * samplePerPixel);
- }
+ if (String.valueOf(ExifTag.Compression.JPEG).equals(typeTagTruth)) {
+ assertTrue(getImageTitle(), type == ExifTag.Compression.JPEG);
+ assertTrue(getImageTitle(), exifData.hasCompressedThumbnail());
+ byte[] thumbnail = exifData.getCompressedThumbnail();
+ assertTrue(getImageTitle(),
+ BitmapFactory.decodeByteArray(thumbnail, 0, thumbnail.length) != null);
+ } else if (String.valueOf(ExifTag.Compression.UNCOMPRESSION).equals(typeTagTruth)) {
+ assertTrue(getImageTitle(), type == ExifTag.Compression.UNCOMPRESSION);
+ // Try to check the strip count with the formula provided by EXIF spec.
+ int planarType = ExifTag.PlanarConfiguration.CHUNKY;
+ ExifTag planarTag = ifd1.getTag(ExifTag.TAG_PLANAR_CONFIGURATION);
+ if (planarTag != null) {
+ planarType = planarTag.getUnsignedShort(0);
+ }
- for (int i = 0; i < stripCount; i++) {
- ExifTag byteCountTag = ifd1.getTag(ExifTag.TAG_STRIP_BYTE_COUNTS);
- if (byteCountTag.getDataType() == ExifTag.TYPE_UNSIGNED_SHORT) {
- assertEquals(getImageTitle(),
- byteCountTag.getUnsignedShort(i), exifData.getStrip(i).length);
- } else {
- assertEquals(getImageTitle(),
- byteCountTag.getUnsignedLong(i), exifData.getStrip(i).length);
- }
+ if (!ifd1Truth.containsKey(ExifTag.TAG_IMAGE_LENGTH) ||
+ !ifd1Truth.containsKey(ExifTag.TAG_ROWS_PER_STRIP)) return;
+
+ ExifTag heightTag = ifd1.getTag(ExifTag.TAG_IMAGE_LENGTH);
+ ExifTag rowPerStripTag = ifd1.getTag(ExifTag.TAG_ROWS_PER_STRIP);
+
+ // Fail the test if required tags are missing
+ if (heightTag == null || rowPerStripTag == null) fail(getImageTitle());
+
+ int imageLength = getUnsignedIntOrShort(heightTag);
+ int rowsPerStrip = getUnsignedIntOrShort(rowPerStripTag);
+ int stripCount = ifd1.getTag(
+ ExifTag.TAG_STRIP_OFFSETS).getComponentCount();
+
+ if (planarType == ExifTag.PlanarConfiguration.CHUNKY) {
+ assertTrue(getImageTitle(),
+ stripCount == (imageLength + rowsPerStrip - 1) / rowsPerStrip);
+ } else {
+ if (!ifd1Truth.containsKey(ExifTag.TAG_SAMPLES_PER_PIXEL)) return;
+ ExifTag samplePerPixelTag = ifd1.getTag(ExifTag.TAG_SAMPLES_PER_PIXEL);
+ int samplePerPixel = samplePerPixelTag.getUnsignedShort(0);
+ assertTrue(getImageTitle(),
+ stripCount ==
+ (imageLength + rowsPerStrip - 1) / rowsPerStrip * samplePerPixel);
+ }
+
+ if (!ifd1Truth.containsKey(ExifTag.TAG_STRIP_BYTE_COUNTS)) return;
+ ExifTag byteCountTag = ifd1.getTag(ExifTag.TAG_STRIP_BYTE_COUNTS);
+ short byteCountDataType = byteCountTag.getDataType();
+ for (int i = 0; i < stripCount; i++) {
+ if (byteCountDataType == ExifTag.TYPE_UNSIGNED_SHORT) {
+ assertEquals(getImageTitle(),
+ byteCountTag.getUnsignedShort(i), exifData.getStrip(i).length);
+ } else {
+ assertEquals(getImageTitle(),
+ byteCountTag.getUnsignedLong(i), exifData.getStrip(i).length);
}
}
}