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

Commit 976bbacc authored by Jaesung Chung's avatar Jaesung Chung Committed by Android (Google) Code Review
Browse files

Merge "ExifInterface: close the resource after reading EXIF data explicitly" into nyc-dev

parents 203ed4d5 c247791d
Loading
Loading
Loading
Loading
+62 −42
Original line number Diff line number Diff line
@@ -651,6 +651,7 @@ public class ExifInterface {
    private final String mFilename;
    private final FileDescriptor mSeekableFileDescriptor;
    private final AssetManager.AssetInputStream mAssetInputStream;
    private final boolean mIsInputStream;
    private boolean mIsRaw;
    private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length];
    private boolean mHasThumbnail;
@@ -669,20 +670,26 @@ public class ExifInterface {
        if (filename == null) {
            throw new IllegalArgumentException("filename cannot be null");
        }
        FileInputStream in = new FileInputStream(filename);
        FileInputStream in = null;
        mAssetInputStream = null;
        mFilename = filename;
        mIsInputStream = false;
        try {
            in = new FileInputStream(filename);
            if (isSeekableFD(in.getFD())) {
                mSeekableFileDescriptor = in.getFD();
            } else {
                mSeekableFileDescriptor = null;
            }
            loadAttributes(in);
        } finally {
            IoUtils.closeQuietly(in);
        }
    }

    /**
     * Reads Exif tags from the specified image file descriptor. Attribute mutation is supported
     * for seekable file descriptors only.
     * for writable and seekable file descriptors only.
     */
    public ExifInterface(FileDescriptor fileDescriptor) throws IOException {
        if (fileDescriptor == null) {
@@ -692,10 +699,25 @@ public class ExifInterface {
        mFilename = null;
        if (isSeekableFD(fileDescriptor)) {
            mSeekableFileDescriptor = fileDescriptor;
            // Keep the original file descriptor in order to save attributes when it's seekable.
            // Otherwise, just close the given file descriptor after reading it because the save
            // feature won't be working.
            try {
                fileDescriptor = Os.dup(fileDescriptor);
            } catch (ErrnoException e) {
                e.rethrowAsIOException();
            }
        } else {
            mSeekableFileDescriptor = null;
        }
        loadAttributes(new FileInputStream(fileDescriptor));
        mIsInputStream = false;
        FileInputStream in = null;
        try {
            in = new FileInputStream(fileDescriptor);
            loadAttributes(in);
        } finally {
            IoUtils.closeQuietly(in);
        }
    }

    /**
@@ -718,6 +740,7 @@ public class ExifInterface {
            mAssetInputStream = null;
            mSeekableFileDescriptor = null;
        }
        mIsInputStream = true;
        loadAttributes(inputStream);
    }

@@ -800,6 +823,7 @@ public class ExifInterface {
     * determine whether the image data format is JPEG or not.
     */
    private void loadAttributes(@NonNull InputStream in) throws IOException {
        try {
            // Initialize mAttributes.
            for (int i = 0; i < EXIF_TAGS.length; ++i) {
                mAttributes[i] = new HashMap();
@@ -825,7 +849,6 @@ public class ExifInterface {
            }

            // Process JPEG input stream
        try {
            getJpegAttributes(in);
        } catch (IOException e) {
            // Ignore exceptions in order to keep the compatibility with the old versions of
@@ -833,12 +856,12 @@ public class ExifInterface {
            Log.w(TAG, "Invalid JPEG: ExifInterface got an unsupported image format file"
                    + "(ExifInterface supports JPEG and some RAW image formats only) "
                    + "or a corrupted JPEG file to ExifInterface.", e);
        }

        } finally {
            if (DEBUG) {
                printAttributes();
            }
        }
    }

    private static boolean isJpegInputStream(BufferedInputStream in) throws IOException {
        in.mark(JPEG_SIGNATURE_SIZE);
@@ -880,10 +903,6 @@ public class ExifInterface {
                    break;
            }
        }

        if (DEBUG) {
            printAttributes();
        }
        return true;
    }

@@ -917,7 +936,7 @@ public class ExifInterface {
            throw new UnsupportedOperationException(
                    "ExifInterface does not support saving attributes on RAW formats.");
        }
        if (mSeekableFileDescriptor == null && mFilename == null) {
        if (mIsInputStream || (mSeekableFileDescriptor == null && mFilename == null)) {
            throw new UnsupportedOperationException(
                    "ExifInterface does not support saving attributes for the current input.");
        }
@@ -1003,8 +1022,9 @@ public class ExifInterface {
            } else if (mFilename != null) {
                in = new FileInputStream(mFilename);
            } else if (mSeekableFileDescriptor != null) {
                Os.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET);
                in = new FileInputStream(mSeekableFileDescriptor);
                FileDescriptor fileDescriptor = Os.dup(mSeekableFileDescriptor);
                Os.lseek(fileDescriptor, 0, OsConstants.SEEK_SET);
                in = new FileInputStream(fileDescriptor);
            }
            if (in == null) {
                // Should not be reached this.