Skip to content

fix: read EXIF orientation directly for plain file paths - #156

Merged
dcalhoun merged 2 commits into
trunkfrom
fix/skip-mediastore-orientation-query-for-file-paths
Aug 20, 2026
Merged

fix: read EXIF orientation directly for plain file paths#156
dcalhoun merged 2 commits into
trunkfrom
fix/skip-mediastore-orientation-query-for-file-paths

Conversation

@dcalhoun

@dcalhoun dcalhoun commented Jul 23, 2026

Copy link
Copy Markdown
Member

Description

ImageUtils.getImageOrientation prefixes any non-content:// path with content://media and queries the MediaStore content provider first, only falling back to reading EXIF when that query returns nothing.

For a plain filesystem path pointing at an existing file (e.g. an app cache file), that constructed Uri is never resolvable through MediaStore, so the query always fails. On some devices it fails by throwing IllegalArgumentException: Volume data not found, which is caught but logged as an error with a full stack trace on every call:

E  Error reading orientation of the file: /data/user/0/<app>/cache/.../image.jpg
   java.lang.IllegalArgumentException: Volume data not found
       at android.database.DatabaseUtils.readExceptionFromParcel(...)
       ...
       at org.wordpress.android.util.ImageUtils.getImageOrientation(ImageUtils.java:100)
       at org.wordpress.android.util.ImageUtils.optimizeImage(ImageUtils.java:547)

The orientation was still resolved correctly (via the EXIF fallback), so this was benign but noisy — and increasingly common now that hosts optimize images staged in their own cache directories (e.g. GutenbergKit's native media upload processing).

Fix

When the path is a plain filesystem path that points at an existing file, read EXIF orientation directly and skip the doomed provider query. EXIF is the only orientation source such a file has, so this is behavior-preserving. MediaStore-style paths (which don't exist on the filesystem) keep the previous query-then-EXIF-fallback behavior.

Testing

Verified in a host app (wordpress-mobile/WordPress-Android#23142) that optimizes an image staged in its cache dir: before this change the error + stack trace logged on every upload; after, it's gone and orientation is still applied correctly.

Co-authored with Claude.

getImageOrientation prefixed non-content paths with "content://media"
and queried the MediaStore content provider first, falling back to EXIF
when that failed. For a plain filesystem path pointing at an existing
file (e.g. an app cache file), that constructed Uri is never resolvable
and the query always fails — on some devices by throwing
IllegalArgumentException ("Volume data not found"), which was logged
as an error with a stack trace on every call.

Such files carry their orientation only in EXIF, so read it directly
and skip the doomed provider query. MediaStore-style paths (which do
not exist on the filesystem) keep the previous behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nbradbury

Copy link
Copy Markdown
Contributor

@dcalhoun Claude found one issue that you may or may not want to address:

Percent-encoded file:// URIs still fall through. file:///storage/emulated/0/My%20Photo.jpg → after the scheme strip, File("/storage/.../My%20Photo.jpg").exists() is false, so it still takes the old failing-query path and logs the error. Not a regression, but the fix doesn’t cover it. Decoding with Uri.decode() before the File check would close that gap if you’re seeing it in the wild.

The plain-file fast path compared the raw string against the filesystem, so a
percent-encoded path never matched: stripping the scheme from
"file:///sdcard/My%20Photo.jpg" leaves "/sdcard/My%20Photo.jpg", which names
no file, and the call fell through to the MediaStore query this fast path
exists to avoid — logging the same error with a stack trace on every call.

getImageOrientation already strips a "file://" prefix, and
getWPImageSpanThumbnailFromFilePath parses its input as a Uri before passing
it here, so URI-shaped arguments are expected input rather than a
hypothetical.

Try the decoded path as well as the raw one, so a filename containing a
literal '%' still resolves undecoded.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dcalhoun
dcalhoun force-pushed the fix/skip-mediastore-orientation-query-for-file-paths branch from 3860bb8 to f375205 Compare August 19, 2026 18:58
@dcalhoun dcalhoun added the bug label Aug 19, 2026
@dcalhoun

Copy link
Copy Markdown
Member Author

@nbradbury I addressed the feedback comment and retested. I believe this ready for another review.

@nbradbury nbradbury left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! :shipit:

@dcalhoun
dcalhoun merged commit a6724fc into trunk Aug 20, 2026
8 checks passed
@dcalhoun
dcalhoun deleted the fix/skip-mediastore-orientation-query-for-file-paths branch August 20, 2026 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants