summaryrefslogtreecommitdiffstats
path: root/gallerycommon/src/com/android/gallery3d/exif/ExifTag.java
diff options
context:
space:
mode:
Diffstat (limited to 'gallerycommon/src/com/android/gallery3d/exif/ExifTag.java')
-rw-r--r--gallerycommon/src/com/android/gallery3d/exif/ExifTag.java168
1 files changed, 78 insertions, 90 deletions
diff --git a/gallerycommon/src/com/android/gallery3d/exif/ExifTag.java b/gallerycommon/src/com/android/gallery3d/exif/ExifTag.java
index 49cb6edbc..cda67c2e2 100644
--- a/gallerycommon/src/com/android/gallery3d/exif/ExifTag.java
+++ b/gallerycommon/src/com/android/gallery3d/exif/ExifTag.java
@@ -18,6 +18,7 @@ package com.android.gallery3d.exif;
import android.util.SparseArray;
+import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
@@ -156,7 +157,7 @@ public class ExifTag {
public static final short TAG_GPS_DEST_DISTANCE = 26;
public static final short TAG_GPS_PROCESSING_METHOD = 27;
public static final short TAG_GPS_AREA_INFORMATION = 28;
- public static final short TAG_GPS_DATA_STAMP = 29;
+ public static final short TAG_GPS_DATE_STAMP = 29;
public static final short TAG_GPS_DIFFERENTIAL = 30;
// Interoperability tag
@@ -827,12 +828,13 @@ public class ExifTag {
(IfdId.TYPE_IFD_GPS << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
sTagInfo.put(TAG_GPS_AREA_INFORMATION,
(IfdId.TYPE_IFD_GPS << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
- sTagInfo.put(TAG_GPS_DATA_STAMP,
+ sTagInfo.put(TAG_GPS_DATE_STAMP,
(IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 11);
sTagInfo.put(TAG_GPS_DIFFERENTIAL,
(IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_SHORT << 16 | 11);
}
+ private static Charset US_ASCII = Charset.forName("US-ASCII");
private final short mTagId;
private final short mDataType;
private final int mIfd;
@@ -911,6 +913,13 @@ public class ExifTag {
IfdId.TYPE_IFD_INTEROPERABILITY);
}
+ static boolean isValidType(short type) {
+ return type == TYPE_UNSIGNED_BYTE || type == TYPE_ASCII ||
+ type == TYPE_UNSIGNED_SHORT || type == TYPE_UNSIGNED_LONG ||
+ type == TYPE_UNSIGNED_RATIONAL || type == TYPE_UNDEFINED ||
+ type == TYPE_LONG || type == TYPE_RATIONAL;
+ }
+
ExifTag(short tagId, short type, int componentCount, int ifd) {
mTagId = tagId;
mDataType = type;
@@ -970,6 +979,15 @@ public class ExifTag {
}
/**
+ * Sets the component count of this tag.
+ * Call this function before setValue() if the length of value does not
+ * match the component count.
+ */
+ public void setComponentCount(int count) {
+ mComponentCount = count;
+ }
+
+ /**
* Returns true if this ExifTag contains value; otherwise, this tag will contain an offset value
* that links to the area where the actual value is located.
*
@@ -1171,18 +1189,37 @@ public class ExifTag {
}
/**
- * Sets string values into this tag.
+ * Sets a string value into this tag. The value is treated as an ASCII string where we only
+ * preserve the lower byte of each character. The length of the string should be equal
+ * to either (component count -1) or (component count). A "0" byte will be appeneded while
+ * written to the EXIF file. If the length equals (component count), the final byte will be
+ * replaced by a "0" byte.
+ *
* @exception IllegalArgumentException If the data type is not {@link #TYPE_ASCII}
- * or value.length() + 1 does NOT fit the definition of the component count in the
- * EXIF standard.
+ * or the length of the string is not equal to (component count -1) and (component count)
*/
public void setValue(String value) {
- checkComponentCountOrThrow(value.length() + 1);
if (mDataType != TYPE_ASCII) {
throwTypeNotMatchedException("String");
}
- mComponentCount = value.length() + 1;
- mValue = value;
+
+ byte[] buf = new byte[value.length()];
+ for (int i = 0, n = value.length(); i < n; i++) {
+ buf[i] = (byte) value.charAt(i);
+ }
+
+ int count = buf.length;
+ if (mComponentCountDefined) {
+ if (mComponentCount != count && mComponentCount != count + 1) {
+ throw new IllegalArgumentException("Tag " + mTagId + ": Required "
+ + mComponentCount + " or " + (mComponentCount + 1)
+ + " components but was given " + count
+ + " component(s)");
+ }
+ } else {
+ mComponentCount = buf[count - 1] == 0 ? count : count + 1;
+ }
+ mValue = buf;
}
/**
@@ -1249,7 +1286,8 @@ public class ExifTag {
setValue(value, 0, value.length);
}
- private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy:MM:dd kk:mm:ss");
+ private static final SimpleDateFormat TIME_FORMAT =
+ new SimpleDateFormat("yyyy:MM:dd kk:mm:ss");
/**
* Sets a timestamp to this tag. The method converts the timestamp with the format of
@@ -1265,41 +1303,23 @@ public class ExifTag {
setValue(TIME_FORMAT.format(new Date(time)));
}
}
-
- /**
- * Gets the {@link #TYPE_UNSIGNED_SHORT} data.
- * @exception IllegalArgumentException If the type is NOT {@link #TYPE_UNSIGNED_SHORT}.
- */
- public int getUnsignedShort(int index) {
- if (mDataType != TYPE_UNSIGNED_SHORT) {
- throw new IllegalArgumentException("Cannot get UNSIGNED_SHORT value from "
- + convertTypeToString(mDataType));
- }
- return (int) (((long[]) mValue) [index]);
- }
-
- /**
- * Gets the {@link #TYPE_LONG} data.
- * @exception IllegalArgumentException If the type is NOT {@link #TYPE_LONG}.
- */
- public int getLong(int index) {
- if (mDataType != TYPE_LONG) {
- throw new IllegalArgumentException("Cannot get LONG value from "
- + convertTypeToString(mDataType));
- }
- return (int) (((long[]) mValue) [index]);
- }
-
/**
- * Gets the {@link #TYPE_UNSIGNED_LONG} data.
- * @exception IllegalArgumentException If the type is NOT {@link #TYPE_UNSIGNED_LONG}.
+ * Gets the value for type {@link #TYPE_ASCII}, {@link #TYPE_LONG},
+ * {@link #TYPE_UNDEFINED}, {@link #TYPE_UNSIGNED_BYTE}, {@link #TYPE_UNSIGNED_LONG}, or
+ * {@link #TYPE_UNSIGNED_SHORT}. For {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL},
+ * call {@link #getRational(int)} instead.
+ *
+ * @exception IllegalArgumentException if the data type is {@link #TYPE_RATIONAL} or
+ * {@link #TYPE_UNSIGNED_RATIONAL}.
*/
- public long getUnsignedLong(int index) {
- if (mDataType != TYPE_UNSIGNED_LONG) {
- throw new IllegalArgumentException("Cannot get UNSIGNED LONG value from "
- + convertTypeToString(mDataType));
+ public long getValueAt(int index) {
+ if (mValue instanceof long[]) {
+ return ((long[]) mValue) [index];
+ } else if (mValue instanceof byte[]) {
+ return ((byte[]) mValue) [index];
}
- return ((long[]) mValue) [index];
+ throw new IllegalArgumentException("Cannot get integer value from "
+ + convertTypeToString(mDataType));
}
/**
@@ -1311,7 +1331,14 @@ public class ExifTag {
throw new IllegalArgumentException("Cannot get ASCII value from "
+ convertTypeToString(mDataType));
}
- return (String) mValue;
+ return new String((byte[]) mValue, US_ASCII);
+ }
+
+ /*
+ * Get the converted ascii byte. Used by ExifOutputStream.
+ */
+ byte[] getStringByte() {
+ return (byte[]) mValue;
}
/**
@@ -1355,54 +1382,6 @@ public class ExifTag {
}
/**
- * Returns a string representation of the value of this tag.
- */
- public String valueToString() {
- StringBuilder sbuilder = new StringBuilder();
- switch (getDataType()) {
- case ExifTag.TYPE_UNDEFINED:
- case ExifTag.TYPE_UNSIGNED_BYTE:
- byte buf[] = new byte[getComponentCount()];
- getBytes(buf);
- for(int i = 0, n = getComponentCount(); i < n; i++) {
- if(i != 0) sbuilder.append(" ");
- sbuilder.append(String.format("%02x", buf[i]));
- }
- break;
- case ExifTag.TYPE_ASCII:
- sbuilder.append(getString());
- break;
- case ExifTag.TYPE_UNSIGNED_LONG:
- for(int i = 0, n = getComponentCount(); i < n; i++) {
- if(i != 0) sbuilder.append(" ");
- sbuilder.append(getUnsignedLong(i));
- }
- break;
- case ExifTag.TYPE_RATIONAL:
- case ExifTag.TYPE_UNSIGNED_RATIONAL:
- 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, n = getComponentCount(); i < n; i++) {
- if(i != 0) sbuilder.append(" ");
- sbuilder.append(getUnsignedShort(i));
- }
- break;
- case ExifTag.TYPE_LONG:
- for(int i = 0, n = getComponentCount(); i < n; i++) {
- if(i != 0) sbuilder.append(" ");
- sbuilder.append(getLong(i));
- }
- break;
- }
- return sbuilder.toString();
- }
-
- /**
* Returns true if the ID is one of the following: {@link #TAG_EXIF_IFD},
* {@link #TAG_GPS_IFD}, {@link #TAG_JPEG_INTERCHANGE_FORMAT},
* {@link #TAG_STRIP_OFFSETS}, {@link #TAG_INTEROPERABILITY_IFD}
@@ -1415,6 +1394,15 @@ public class ExifTag {
|| tagId == TAG_INTEROPERABILITY_IFD;
}
+ /**
+ * Returns true if the ID is one of the following: {@link #TAG_EXIF_IFD},
+ * {@link #TAG_GPS_IFD}, {@link #TAG_INTEROPERABILITY_IFD}
+ */
+ static boolean isSubIfdOffsetTag(short tagId) {
+ return tagId == TAG_EXIF_IFD
+ || tagId == TAG_GPS_IFD
+ || tagId == TAG_INTEROPERABILITY_IFD;
+ }
@Override
public boolean equals(Object obj) {
if (obj instanceof ExifTag) {