summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/gallery3d/exif/ExifParser.java15
-rw-r--r--src/com/android/gallery3d/exif/ExifTag.java200
-rw-r--r--tests/src/com/android/gallery3d/exif/ExifParserTest.java2
-rw-r--r--tests/src/com/android/gallery3d/exif/ExifReaderTest.java10
4 files changed, 160 insertions, 67 deletions
diff --git a/src/com/android/gallery3d/exif/ExifParser.java b/src/com/android/gallery3d/exif/ExifParser.java
index 268c989b0..f6ecd7798 100644
--- a/src/com/android/gallery3d/exif/ExifParser.java
+++ b/src/com/android/gallery3d/exif/ExifParser.java
@@ -405,7 +405,7 @@ public class ExifParser {
*/
public int getCompressedImageSize() {
if (mJpegSizeTag == null) return 0;
- return (int) mJpegSizeTag.getUnsignedInt();
+ return (int) mJpegSizeTag.getUnsignedInt(0);
}
private void skipTo(int offset) throws IOException {
@@ -449,7 +449,8 @@ public class ExifParser {
"Number of component is larger then Integer.MAX_VALUE");
}
ExifTag tag = new ExifTag(tagId, dataFormat, (int) numOfComp, mIfdType);
- if (tag.getDataSize() > 4) {
+ int dataSize = tag.getDataSize();
+ if (dataSize > 4) {
long offset = mTiffStream.readUnsignedInt();
if (offset > Integer.MAX_VALUE) {
throw new ExifInvalidFormatException(
@@ -458,7 +459,7 @@ public class ExifParser {
tag.setOffset((int) offset);
} else {
readFullTagValue(tag);
- mTiffStream.skip(4 - tag.getDataSize());
+ mTiffStream.skip(4 - dataSize);
}
return tag;
}
@@ -472,22 +473,22 @@ public class ExifParser {
case ExifTag.TIFF_TAG.TAG_EXIF_IFD:
if (isIfdRequested(IfdId.TYPE_IFD_EXIF)
|| isIfdRequested(IfdId.TYPE_IFD_INTEROPERABILITY)) {
- registerIfd(IfdId.TYPE_IFD_EXIF, tag.getUnsignedInt());
+ registerIfd(IfdId.TYPE_IFD_EXIF, tag.getUnsignedInt(0));
}
break;
case ExifTag.TIFF_TAG.TAG_GPS_IFD:
if (isIfdRequested(IfdId.TYPE_IFD_GPS)) {
- registerIfd(IfdId.TYPE_IFD_GPS, tag.getUnsignedInt());
+ registerIfd(IfdId.TYPE_IFD_GPS, tag.getUnsignedInt(0));
}
break;
case ExifTag.EXIF_TAG.TAG_INTEROPERABILITY_IFD:
if (isIfdRequested(IfdId.TYPE_IFD_INTEROPERABILITY)) {
- registerIfd(IfdId.TYPE_IFD_INTEROPERABILITY, tag.getUnsignedInt());
+ registerIfd(IfdId.TYPE_IFD_INTEROPERABILITY, tag.getUnsignedInt(0));
}
break;
case ExifTag.TIFF_TAG.TAG_JPEG_INTERCHANGE_FORMAT:
if (isThumbnailRequested()) {
- registerCompressedImage(tag.getUnsignedInt());
+ registerCompressedImage(tag.getUnsignedInt(0));
}
break;
case ExifTag.TIFF_TAG.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH:
diff --git a/src/com/android/gallery3d/exif/ExifTag.java b/src/com/android/gallery3d/exif/ExifTag.java
index 7b5a2eb6b..b2cbe61d7 100644
--- a/src/com/android/gallery3d/exif/ExifTag.java
+++ b/src/com/android/gallery3d/exif/ExifTag.java
@@ -363,8 +363,8 @@ public class ExifTag {
private final short mTagId;
private final short mDataType;
- private final int mComponentCount;
private final int mIfd;
+ private int mComponentCount;
private Object mValue;
private int mOffset;
@@ -451,83 +451,175 @@ public class ExifTag {
}
/**
- * Sets the value of this tag. This is useful when we want to modify the tags and write it back
- * to the JPEG file
+ * Sets integer values into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to the length.
*/
- public void setValue(Object object) {
- if (object.getClass().isArray()) {
- assert(mComponentCount == Array.getLength(object));
- mValue = object;
- } else if (object instanceof String) {
- assert(mComponentCount == ((String) object).length() + 1);
- mValue = object;
- } else {
- // Wrap object with an array because user may try to get object by get method with
- // index 0 when size = 1
- // e.g. getShort(0)
- assert(mComponentCount == 1);
- Object array = Array.newInstance(object.getClass(), 1);
- Array.set(array, 0, object);
- mValue = array;
+ public void setValue(int[] value) {
+ long[] data = new long[value.length];
+ for (int i = 0; i < value.length; i++) {
+ data[i] = value[i];
}
+ mValue = data;
+ mComponentCount = value.length;
}
- public short getShort(int index) {
- return (Short) Array.get(mValue, index);
+ /**
+ * Sets integer value into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to 1.
+ */
+ public void setValue(int value) {
+ mValue = new long[] {value};
+ mComponentCount = 1;
}
- public short getShort() {
- return (Short) Array.get(mValue, 0);
+ /**
+ * Sets short values into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to the length.
+ */
+ public void setValue(short[] value) {
+ long[] data = new long[value.length];
+ for (int i = 0; i < value.length; i++) {
+ data[i] = value[i];
+ }
+ mValue = data;
+ mComponentCount = value.length;
}
- public int getUnsignedShort(int index) {
- return (Integer) Array.get(mValue, index);
+ /**
+ * Sets short value into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to 1.
+ */
+ public void setValue(short value) {
+ mValue = new long[] {value};
+ mComponentCount = 1;
}
- public int getUnsignedShort() {
- return (Integer) Array.get(mValue, 0);
+ /**
+ * Sets long values into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to the length.
+ */
+ public void setValue(long[] value) {
+ long[] data = new long[value.length];
+ System.arraycopy(value, 0, data, 0, value.length);
+ mValue = data;
+ mComponentCount = value.length;
}
- public int getInt(int index) {
- return (Integer) Array.get(mValue, index);
+ /**
+ * Sets long value into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to 1.
+ */
+ public void setValue(long value) {
+ mValue = new long[] {value};
+ mComponentCount = 1;
}
- public int getInt() {
- return (Integer) Array.get(mValue, 0);
+ /**
+ * Sets String value into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to
+ * value.length() + 1.
+ */
+ public void setValue(String value) {
+ mComponentCount = value.length() + 1;
+ mValue = value;
}
- public long getUnsignedInt(int index) {
- return (Long) Array.get(mValue, index);
+ /**
+ * Sets Rational values into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to the length.
+ */
+ public void setValue(Rational[] value) {
+ mValue = new Rational[value.length];
+ System.arraycopy(value, 0, mValue, 0, value.length);
+ mComponentCount = value.length;
}
- public long getUnsignedInt() {
- return (Long) Array.get(mValue, 0);
+ /**
+ * Sets Rational value into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to 1.
+ */
+ public void setValue(Rational value) {
+ mValue = new Rational[] {value};
+ mComponentCount = 1;
}
- public String getString() {
- return (String) mValue;
+ /**
+ * Sets byte values into this tag. This is useful when we want to modify the tags
+ * and write it back to the JPEG file. The component count will be set to the length.
+ */
+ public void setValue(byte[] value, int offset, int length) {
+ long[] data = new long[length];
+ for (int i = 0; i < length; i++) {
+ data[i] = value[i + offset];
+ }
+ mValue = data;
+ mComponentCount = length;
}
- public Rational getRational(int index) {
- return ((Rational[]) mValue)[index];
+ /**
+ * Sets the byte array as the value of this tag.
+ * This is equivalent to setValue(value, 0, value.length).
+ */
+ public void setValue(byte[] value) {
+ setValue(value, 0, value.length);
+ }
+
+ public short getShort(int index) {
+ if (mValue instanceof long[]) {
+ return (short) (((long[]) mValue) [index]);
+ } else {
+ throw new RuntimeException("There is numerical value in this tag");
+ }
+ }
+
+ public int getUnsignedShort(int index) {
+ if (mValue instanceof long[]) {
+ return (int) (((long[]) mValue) [index]);
+ } else {
+ throw new RuntimeException("There is numerical value in this tag");
+ }
+ }
+
+ public int getInt(int index) {
+ if (mValue instanceof long[]) {
+ return (int) (((long[]) mValue) [index]);
+ } else {
+ throw new RuntimeException("There is numerical value in this tag");
+ }
}
- public Rational getRational() {
- return ((Rational[]) mValue)[0];
+ public long getUnsignedInt(int index) {
+ if (mValue instanceof long[]) {
+ return ((long[]) mValue) [index];
+ } else {
+ throw new RuntimeException("There is numerical value in this tag");
+ }
}
- public int getBytes(byte[] buf) {
- return getBytes(buf, 0, buf.length);
+ public String getString() {
+ return (String) mValue;
}
- public int getBytes(byte[] buf, int offset, int length) {
- byte[] data = (byte[]) mValue;
- if (data.length < length + offset) {
- System.arraycopy(data, offset, buf, 0, data.length - offset);
- return data.length - offset;
+ public Rational getRational(int index) {
+ Object value = Array.get(mValue, index);
+ if (value instanceof Rational) {
+ return (Rational) value;
} else {
- System.arraycopy(data, offset, buf, 0, length);
- return length;
+ throw new RuntimeException("There is no Rational value in this tag");
+ }
+ }
+
+ public void getBytes(byte[] buf) {
+ getBytes(buf, 0, buf.length);
+ }
+
+ public void getBytes(byte[] buf, int offset, int length) {
+ if (!(mValue instanceof long[])) {
+ throw new RuntimeException("There is no byte value in this tag");
+ }
+ long[] data = (long[]) mValue;
+ for(int i = 0; i < length; i++) {
+ buf[offset + i] = (byte) data[i];
}
}
@@ -541,7 +633,7 @@ public class ExifTag {
case ExifTag.TYPE_UNSIGNED_BYTE:
byte buf[] = new byte[getComponentCount()];
getBytes(buf);
- for(int i = 0; i < getComponentCount(); i++) {
+ for(int i = 0, n = getComponentCount(); i < n; i++) {
if(i != 0) sbuilder.append(" ");
sbuilder.append(String.format("%02x", buf[i]));
}
@@ -551,27 +643,27 @@ public class ExifTag {
sbuilder.append(getString().trim());
break;
case ExifTag.TYPE_UNSIGNED_INT:
- for(int i = 0; i < getComponentCount(); i++) {
+ for(int i = 0, n = getComponentCount(); i < n; i++) {
if(i != 0) sbuilder.append(" ");
sbuilder.append(getUnsignedInt(i));
}
break;
case ExifTag.TYPE_RATIONAL:
case ExifTag.TYPE_UNSIGNED_RATIONAL:
- for(int i = 0; i < getComponentCount(); i++) {
+ for(int i = 0, n = getComponentCount(); i < n; i++) {
Rational r = getRational(i);
if(i != 0) sbuilder.append(" ");
sbuilder.append(r.getNominator()).append("/").append(r.getDenominator());
}
break;
case ExifTag.TYPE_UNSIGNED_SHORT:
- for(int i = 0; i < getComponentCount(); i++) {
+ for(int i = 0, n = getComponentCount(); i < n; i++) {
if(i != 0) sbuilder.append(" ");
sbuilder.append(getUnsignedShort(i));
}
break;
case ExifTag.TYPE_INT:
- for(int i = 0; i < getComponentCount(); i++) {
+ for(int i = 0, n = getComponentCount(); i < n; i++) {
if(i != 0) sbuilder.append(" ");
sbuilder.append(getInt(i));
}
diff --git a/tests/src/com/android/gallery3d/exif/ExifParserTest.java b/tests/src/com/android/gallery3d/exif/ExifParserTest.java
index 241aaf575..e967e3d28 100644
--- a/tests/src/com/android/gallery3d/exif/ExifParserTest.java
+++ b/tests/src/com/android/gallery3d/exif/ExifParserTest.java
@@ -210,7 +210,7 @@ public class ExifParserTest extends InstrumentationTestCase {
case ExifParser.EVENT_NEW_TAG:
ExifTag tag = parser.getTag();
if (tag.getTagId() == ExifTag.TIFF_TAG.TAG_COMPRESSION) {
- if (tag.getUnsignedShort() == ExifTag.TIFF_TAG.COMPRESSION_JPEG) {
+ if (tag.getUnsignedShort(0) == ExifTag.TIFF_TAG.COMPRESSION_JPEG) {
mIsContainCompressedImage = true;
}
}
diff --git a/tests/src/com/android/gallery3d/exif/ExifReaderTest.java b/tests/src/com/android/gallery3d/exif/ExifReaderTest.java
index 67e695682..e5b51f162 100644
--- a/tests/src/com/android/gallery3d/exif/ExifReaderTest.java
+++ b/tests/src/com/android/gallery3d/exif/ExifReaderTest.java
@@ -69,7 +69,7 @@ public class ExifReaderTest extends InstrumentationTestCase {
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() ==
+ if (ifd1.getTag(ExifTag.TIFF_TAG.TAG_COMPRESSION).getUnsignedShort(0) ==
ExifTag.TIFF_TAG.COMPRESSION_JPEG) {
assertTrue(exifData.hasCompressedThumbnail());
byte[] thumbnail = exifData.getCompressedThumbnail();
@@ -79,7 +79,7 @@ public class ExifReaderTest extends InstrumentationTestCase {
int planarType = ExifTag.TIFF_TAG.PLANAR_CONFIGURATION_CHUNKY;
ExifTag planarTag = ifd1.getTag(ExifTag.TIFF_TAG.TAG_PLANAR_CONFIGURATION);
if (planarTag != null) {
- planarType = planarTag.getUnsignedShort();
+ planarType = planarTag.getUnsignedShort(0);
}
ExifTag heightTag = ifd1.getTag(ExifTag.TIFF_TAG.TAG_IMAGE_HEIGHT);
@@ -94,7 +94,7 @@ public class ExifReaderTest extends InstrumentationTestCase {
assertTrue(stripCount == (imageLength + rowsPerStrip - 1) / rowsPerStrip);
} else {
ExifTag samplePerPixelTag = ifd1.getTag(ExifTag.TIFF_TAG.TAG_SAMPLES_PER_PIXEL);
- int samplePerPixel = samplePerPixelTag.getUnsignedShort();
+ int samplePerPixel = samplePerPixelTag.getUnsignedShort(0);
assertTrue(stripCount ==
(imageLength + rowsPerStrip - 1) / rowsPerStrip * samplePerPixel);
}
@@ -114,9 +114,9 @@ public class ExifReaderTest extends InstrumentationTestCase {
private int getUnsignedIntOrShort(ExifTag tag) {
if (tag.getDataType() == ExifTag.TYPE_UNSIGNED_SHORT) {
- return tag.getUnsignedShort();
+ return tag.getUnsignedShort(0);
} else {
- return (int) tag.getUnsignedInt();
+ return (int) tag.getUnsignedInt(0);
}
}