diff options
Diffstat (limited to 'gallerycommon/src/com/android/gallery3d/exif/ExifTag.java')
-rw-r--r-- | gallerycommon/src/com/android/gallery3d/exif/ExifTag.java | 168 |
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) { |