Merge "ExifInterface: keep tags in the original tag groups" into nyc-dev

am: 41e54ad

* commit '41e54ad3a8e058f35a17eddff9b498dcf872006e':
  ExifInterface: keep tags in the original tag groups

Change-Id: I0d0464b15b0b41157b9dfd6b241612506d6e02d8
This commit is contained in:
Jaesung Chung
2016-03-30 11:08:39 +00:00
committed by android-build-merger

View File

@@ -693,7 +693,7 @@ public class ExifInterface {
*/ */
public ExifInterface(FileDescriptor fileDescriptor) throws IOException { public ExifInterface(FileDescriptor fileDescriptor) throws IOException {
if (fileDescriptor == null) { if (fileDescriptor == null) {
throw new IllegalArgumentException("parcelFileDescriptor cannot be null"); throw new IllegalArgumentException("fileDescriptor cannot be null");
} }
mAssetInputStream = null; mAssetInputStream = null;
mFilename = null; mFilename = null;
@@ -705,7 +705,7 @@ public class ExifInterface {
try { try {
fileDescriptor = Os.dup(fileDescriptor); fileDescriptor = Os.dup(fileDescriptor);
} catch (ErrnoException e) { } catch (ErrnoException e) {
e.rethrowAsIOException(); throw e.rethrowAsIOException();
} }
} else { } else {
mSeekableFileDescriptor = null; mSeekableFileDescriptor = null;
@@ -811,12 +811,44 @@ public class ExifInterface {
*/ */
public void setAttribute(String tag, String value) { public void setAttribute(String tag, String value) {
for (int i = 0 ; i < EXIF_TAGS.length; ++i) { for (int i = 0 ; i < EXIF_TAGS.length; ++i) {
if (i == IFD_THUMBNAIL_HINT && !mHasThumbnail) {
continue;
}
if (sExifTagMapsForWriting[i].containsKey(tag)) { if (sExifTagMapsForWriting[i].containsKey(tag)) {
mAttributes[i].put(tag, value); mAttributes[i].put(tag, value);
} }
} }
} }
/**
* Update the values of the tags in the tag groups if any value for the tag already was stored.
*
* @param tag the name of the tag.
* @param value the value of the tag.
* @return Returns {@code true} if updating is placed.
*/
private boolean updateAttribute(String tag, String value) {
boolean updated = false;
for (int i = 0 ; i < EXIF_TAGS.length; ++i) {
if (mAttributes[i].containsKey(tag)) {
mAttributes[i].put(tag, value);
updated = true;
}
}
return updated;
}
/**
* Remove any values of the specified tag.
*
* @param tag the name of the tag.
*/
private void removeAttribute(String tag) {
for (int i = 0 ; i < EXIF_TAGS.length; ++i) {
mAttributes[i].remove(tag);
}
}
/** /**
* This function decides which parser to read the image data according to the given input stream * This function decides which parser to read the image data according to the given input stream
* type and the content of the input stream. In each case, it reads the first three bytes to * type and the content of the input stream. In each case, it reads the first three bytes to
@@ -853,7 +885,7 @@ public class ExifInterface {
} catch (IOException e) { } catch (IOException e) {
// Ignore exceptions in order to keep the compatibility with the old versions of // Ignore exceptions in order to keep the compatibility with the old versions of
// ExifInterface. // ExifInterface.
Log.w(TAG, "Invalid JPEG: ExifInterface got an unsupported image format file" Log.w(TAG, "Invalid image: ExifInterface got an unsupported image format file"
+ "(ExifInterface supports JPEG and some RAW image formats only) " + "(ExifInterface supports JPEG and some RAW image formats only) "
+ "or a corrupted JPEG file to ExifInterface.", e); + "or a corrupted JPEG file to ExifInterface.", e);
} finally { } finally {
@@ -882,27 +914,22 @@ public class ExifInterface {
// Mark for disabling the save feature. // Mark for disabling the save feature.
mIsRaw = true; mIsRaw = true;
for (Map.Entry entry : (Set<Map.Entry>) map.entrySet()) { String value = (String) map.remove(TAG_HAS_THUMBNAIL);
String attrName = (String) entry.getKey(); mHasThumbnail = value != null && value.equalsIgnoreCase("true");
value = (String) map.remove(TAG_THUMBNAIL_OFFSET);
switch (attrName) { if (value != null) {
case TAG_HAS_THUMBNAIL: mThumbnailOffset = Integer.parseInt(value);
mHasThumbnail = ((String) entry.getValue()).equalsIgnoreCase("true");
break;
case TAG_THUMBNAIL_OFFSET:
mThumbnailOffset = Integer.parseInt((String) entry.getValue());
break;
case TAG_THUMBNAIL_LENGTH:
mThumbnailLength = Integer.parseInt((String) entry.getValue());
break;
case TAG_THUMBNAIL_DATA:
mThumbnailBytes = (byte[]) entry.getValue();
break;
default:
setAttribute(attrName, (String) entry.getValue());
break;
}
} }
value = (String) map.remove(TAG_THUMBNAIL_LENGTH);
if (value != null) {
mThumbnailLength = Integer.parseInt(value);
}
mThumbnailBytes = (byte[]) map.remove(TAG_THUMBNAIL_DATA);
for (Map.Entry entry : (Set<Map.Entry>) map.entrySet()) {
setAttribute((String) entry.getKey(), (String) entry.getValue());
}
return true; return true;
} }
@@ -928,7 +955,7 @@ public class ExifInterface {
/** /**
* Save the tag data into the original image file. This is expensive because it involves * Save the tag data into the original image file. This is expensive because it involves
* copying all the data from one file to another and deleting the old file and renaming the * copying all the data from one file to another and deleting the old file and renaming the
* other. It's best to use{@link #setAttribute(String,String)} to set all attributes to write * other. It's best to use {@link #setAttribute(String,String)} to set all attributes to write
* and make a single call rather than multiple calls for each attribute. * and make a single call rather than multiple calls for each attribute.
*/ */
public void saveAttributes() throws IOException { public void saveAttributes() throws IOException {
@@ -963,7 +990,7 @@ public class ExifInterface {
Streams.copy(in, out); Streams.copy(in, out);
} }
} catch (ErrnoException e) { } catch (ErrnoException e) {
e.rethrowAsIOException(); throw e.rethrowAsIOException();
} finally { } finally {
IoUtils.closeQuietly(in); IoUtils.closeQuietly(in);
IoUtils.closeQuietly(out); IoUtils.closeQuietly(out);
@@ -982,7 +1009,7 @@ public class ExifInterface {
} }
saveJpegAttributes(in, out); saveJpegAttributes(in, out);
} catch (ErrnoException e) { } catch (ErrnoException e) {
e.rethrowAsIOException(); throw e.rethrowAsIOException();
} finally { } finally {
IoUtils.closeQuietly(in); IoUtils.closeQuietly(in);
IoUtils.closeQuietly(out); IoUtils.closeQuietly(out);
@@ -1276,7 +1303,8 @@ public class ExifInterface {
throw new IOException("Invalid exif"); throw new IOException("Invalid exif");
} }
length = 0; length = 0;
setAttribute("UserComment", new String(bytes, Charset.forName("US-ASCII"))); mAttributes[IFD_EXIF_HINT].put(TAG_USER_COMMENT,
new String(bytes, Charset.forName("US-ASCII")));
break; break;
} }
@@ -1296,9 +1324,10 @@ public class ExifInterface {
if (dataInputStream.skipBytes(1) != 1) { if (dataInputStream.skipBytes(1) != 1) {
throw new IOException("Invalid SOFx"); throw new IOException("Invalid SOFx");
} }
setAttribute("ImageLength", mAttributes[IFD_TIFF_HINT].put(TAG_IMAGE_LENGTH,
String.valueOf(dataInputStream.readUnsignedShort()));
mAttributes[IFD_TIFF_HINT].put(TAG_IMAGE_WIDTH,
String.valueOf(dataInputStream.readUnsignedShort())); String.valueOf(dataInputStream.readUnsignedShort()));
setAttribute("ImageWidth", String.valueOf(dataInputStream.readUnsignedShort()));
length -= 5; length -= 5;
break; break;
} }
@@ -1521,31 +1550,31 @@ public class ExifInterface {
convertToInt(TAG_GPS_ALTITUDE_REF); convertToInt(TAG_GPS_ALTITUDE_REF);
convertToRational(TAG_GPS_LONGITUDE); convertToRational(TAG_GPS_LONGITUDE);
convertToRational(TAG_GPS_LATITUDE); convertToRational(TAG_GPS_LATITUDE);
convertToTimetamp(TAG_GPS_TIMESTAMP); convertToTimestamp(TAG_GPS_TIMESTAMP);
// The value of DATETIME tag has the same value of DATETIME_ORIGINAL tag. // The value of DATETIME tag has the same value of DATETIME_ORIGINAL tag.
String valueOfDateTimeOriginal = getAttribute("DateTimeOriginal"); String valueOfDateTimeOriginal = getAttribute(TAG_DATETIME_ORIGINAL);
if (valueOfDateTimeOriginal != null) { if (valueOfDateTimeOriginal != null) {
setAttribute(TAG_DATETIME, valueOfDateTimeOriginal); mAttributes[IFD_TIFF_HINT].put(TAG_DATETIME, valueOfDateTimeOriginal);
} }
// Add the default value. // Add the default value.
if (getAttribute(TAG_IMAGE_WIDTH) == null) { if (getAttribute(TAG_IMAGE_WIDTH) == null) {
setAttribute(TAG_IMAGE_WIDTH, "0"); mAttributes[IFD_TIFF_HINT].put(TAG_IMAGE_WIDTH, "0");
} }
if (getAttribute(TAG_IMAGE_LENGTH) == null) { if (getAttribute(TAG_IMAGE_LENGTH) == null) {
setAttribute(TAG_IMAGE_LENGTH, "0"); mAttributes[IFD_TIFF_HINT].put(TAG_IMAGE_LENGTH, "0");
} }
if (getAttribute(TAG_ORIENTATION) == null) { if (getAttribute(TAG_ORIENTATION) == null) {
setAttribute(TAG_ORIENTATION, "0"); mAttributes[IFD_TIFF_HINT].put(TAG_ORIENTATION, "0");
} }
if (getAttribute(TAG_LIGHT_SOURCE) == null) { if (getAttribute(TAG_LIGHT_SOURCE) == null) {
setAttribute(TAG_LIGHT_SOURCE, "0"); mAttributes[IFD_EXIF_HINT].put(TAG_LIGHT_SOURCE, "0");
} }
} }
// Converts the tag value to timestamp; Otherwise deletes the given tag. // Converts the tag value to timestamp; Otherwise deletes the given tag.
private void convertToTimetamp(String tagName) { private void convertToTimestamp(String tagName) {
String entryValue = getAttribute(tagName); String entryValue = getAttribute(tagName);
if (entryValue == null) return; if (entryValue == null) return;
int dataFormat = getDataFormatOfExifEntryValue(entryValue); int dataFormat = getDataFormatOfExifEntryValue(entryValue);
@@ -1566,9 +1595,9 @@ public class ExifInterface {
int value = numerator / denominator; int value = numerator / denominator;
stringBuilder.append(String.format("%02d", value)); stringBuilder.append(String.format("%02d", value));
} }
setAttribute(tagName, stringBuilder.toString()); updateAttribute(tagName, stringBuilder.toString());
} else if (dataFormat != IFD_FORMAT_STRING) { } else if (dataFormat != IFD_FORMAT_STRING) {
setAttribute(tagName, null); removeAttribute(tagName);
} }
} }
@@ -1595,14 +1624,14 @@ public class ExifInterface {
} }
stringBuilder.append((double) numerator / denominator); stringBuilder.append((double) numerator / denominator);
} }
setAttribute(tagName, stringBuilder.toString()); updateAttribute(tagName, stringBuilder.toString());
break; break;
} }
case IFD_FORMAT_DOUBLE: case IFD_FORMAT_DOUBLE:
// Keep it as is. // Keep it as is.
break; break;
default: default:
setAttribute(tagName, null); removeAttribute(tagName);
break; break;
} }
} }
@@ -1624,14 +1653,14 @@ public class ExifInterface {
double doubleValue = Double.parseDouble(component); double doubleValue = Double.parseDouble(component);
stringBuilder.append((int) (doubleValue * 10000.0)).append("/").append(10000); stringBuilder.append((int) (doubleValue * 10000.0)).append("/").append(10000);
} }
setAttribute(tagName, stringBuilder.toString()); updateAttribute(tagName, stringBuilder.toString());
break; break;
} }
case IFD_FORMAT_SRATIONAL: case IFD_FORMAT_SRATIONAL:
// Keep it as is. // Keep it as is.
break; break;
default: default:
setAttribute(tagName, null); removeAttribute(tagName);
break; break;
} }
} }
@@ -1642,7 +1671,7 @@ public class ExifInterface {
if (entryValue == null) return; if (entryValue == null) return;
int dataFormat = getDataFormatOfExifEntryValue(entryValue); int dataFormat = getDataFormatOfExifEntryValue(entryValue);
if (dataFormat != IFD_FORMAT_SLONG) { if (dataFormat != IFD_FORMAT_SLONG) {
setAttribute(tagName, null); removeAttribute(tagName);
} }
} }
@@ -1758,7 +1787,7 @@ public class ExifInterface {
String entryValue = readExifEntryValue( String entryValue = readExifEntryValue(
dataInputStream, dataFormat, numberOfComponents); dataInputStream, dataFormat, numberOfComponents);
if (entryValue != null) { if (entryValue != null) {
setAttribute(tagName, entryValue); mAttributes[hint].put(tagName, entryValue);
} }
} else { } else {
StringBuilder entryValueBuilder = new StringBuilder(); StringBuilder entryValueBuilder = new StringBuilder();
@@ -1769,7 +1798,7 @@ public class ExifInterface {
entryValueBuilder.append(readExifEntryValue( entryValueBuilder.append(readExifEntryValue(
dataInputStream, dataFormat, numberOfComponents)); dataInputStream, dataFormat, numberOfComponents));
} }
setAttribute(tagName, entryValueBuilder.toString()); mAttributes[hint].put(tagName, entryValueBuilder.toString());
} }
if (dataInputStream.peek() != nextEntryOffset) { if (dataInputStream.peek() != nextEntryOffset) {
@@ -1886,11 +1915,11 @@ public class ExifInterface {
// Remove IFD pointer tags (we'll re-add it later.) // Remove IFD pointer tags (we'll re-add it later.)
for (ExifTag tag : IFD_POINTER_TAGS) { for (ExifTag tag : IFD_POINTER_TAGS) {
setAttribute(tag.name, null); removeAttribute(tag.name);
} }
// Remove old thumbnail data // Remove old thumbnail data
setAttribute(JPEG_INTERCHANGE_FORMAT_TAG.name, null); removeAttribute(JPEG_INTERCHANGE_FORMAT_TAG.name);
setAttribute(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name, null); removeAttribute(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name);
// Remove null value tags. // Remove null value tags.
for (int hint = 0; hint < EXIF_TAGS.length; ++hint) { for (int hint = 0; hint < EXIF_TAGS.length; ++hint) {