Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1e20d2c authored by Jaesung Chung's avatar Jaesung Chung
Browse files

ExifInterface: fix writing STRING and SRATIONAL formats

This CL makes ExifInterface determine the data format of rational
numbers and the values which include several components for exif entry
correctly.

Bug: 27614052
Change-Id: Ic3ea64889fad06ef5f636e4635ab7803a9c9ae29
parent 1a506af9
Loading
Loading
Loading
Loading
+31 −11
Original line number Diff line number Diff line
@@ -1995,6 +1995,12 @@ public class ExifInterface {
        int bytesWritten = 0;
        int dataFormat = getDataFormatOfExifEntryValue(entryValue);

        if (dataFormat == IFD_FORMAT_STRING) {
            byte[] asciiArray = (entryValue + '\0').getBytes(Charset.forName("US-ASCII"));
            dataOutputStream.write(asciiArray);
            return asciiArray.length;
        }

        // Values can be composed of several components. Each component is separated by char ','.
        String[] components = entryValue.split(",");
        for (String component : components) {
@@ -2007,11 +2013,6 @@ public class ExifInterface {
                    dataOutputStream.writeDouble(Double.parseDouble(component));
                    bytesWritten += 8;
                    break;
                case IFD_FORMAT_STRING:
                    byte[] asciiArray = (component + '\0').getBytes(Charset.forName("US-ASCII"));
                    dataOutputStream.write(asciiArray);
                    bytesWritten += asciiArray.length;
                    break;
                case IFD_FORMAT_SRATIONAL:
                    String[] rationalNumber = component.split("/");
                    dataOutputStream.writeInt(Integer.parseInt(rationalNumber[0]));
@@ -2030,11 +2031,31 @@ public class ExifInterface {
        // See TIFF 6.0 spec Types. page 15.
        // Take the first component if there are more than one component.
        if (entryValue.contains(",")) {
            entryValue = entryValue.split(",")[0];
            String[] entryValues = entryValue.split(",");
            int dataFormat = getDataFormatOfExifEntryValue(entryValues[0]);
            if (dataFormat == IFD_FORMAT_STRING) {
                return IFD_FORMAT_STRING;
            }
            for (int i = 1; i < entryValues.length; ++i) {
                if (getDataFormatOfExifEntryValue(entryValues[i]) != dataFormat) {
                    return IFD_FORMAT_STRING;
                }
            }
            return dataFormat;
        }

        if (entryValue.contains("/")) {
            String[] rationalNumber = entryValue.split("/");
            if (rationalNumber.length == 2) {
                try {
                    Integer.parseInt(rationalNumber[0]);
                    Integer.parseInt(rationalNumber[1]);
                    return IFD_FORMAT_SRATIONAL;
                } catch (NumberFormatException e)  {
                    // Ignored
                }
            }
            return IFD_FORMAT_STRING;
        }
        try {
            Integer.parseInt(entryValue);
@@ -2054,6 +2075,9 @@ public class ExifInterface {
    // Determines the size of EXIF entry value.
    private static int getSizeOfExifEntryValue(int dataFormat, String entryValue) {
        // See TIFF 6.0 spec Types page 15.
        if (dataFormat == IFD_FORMAT_STRING) {
            return (entryValue + '\0').getBytes(Charset.forName("US-ASCII")).length;
        }
        int bytesEstimated = 0;
        String[] components = entryValue.split(",");
        for (String component : components) {
@@ -2064,10 +2088,6 @@ public class ExifInterface {
                case IFD_FORMAT_DOUBLE:
                    bytesEstimated += 8;
                    break;
                case IFD_FORMAT_STRING:
                    bytesEstimated
                            += (component + '\0').getBytes(Charset.forName("US-ASCII")).length;
                    break;
                case IFD_FORMAT_SRATIONAL:
                    bytesEstimated += 8;
                    break;