Every image in a .docx / .xlsx document comes out as the core's broken-image placeholder. ODF documents are fine, which is what makes it easy to miss.
Found by sweeping OpenDocument.core's input corpus on a Pixel 9 Pro (#550). Roughly 23 of 225 documents are affected — every OOXML file in the corpus that contains an image.
Cause
CoreLoader publishes the translated document on the core's http server under /file/<prefix>/, but asks for absolute resource paths:
https://github.com/opendocument-app/OpenDocument.droid/blob/main/app/src/main/java/app/opendocument/droid/background/CoreLoader.kt#L209-L212
htmlConfig.embedImages = false
htmlConfig.embedShippedResources = true
htmlConfig.relativeResourcePaths = false
For OOXML the core then emits the path as it appears in the container, rooted:
<img alt="Error: image not found or unsupported" src="/word/media/image1.jpeg"/>
The WebView resolves that against the server root, not against /file/odr/, so it misses either way. Both 404 (checked against the running app over adb forward):
/word/media/image1.jpeg HTTP 404
/file/odr/word/media/image1.jpeg HTTP 404
ODF documents work because the core emits their paths relative, and those resolve under the service mount point:
<img src="Pictures/1000000000000303000001E0ABAD3FD0DB2BBAE0.png"/>
/file/odr/Pictures/10000000...png HTTP 200, 434353 bytes, image/jpg
So the server serves document resources correctly; only the absolute form misses.
Neither of the two settings that look like the fix is one. relativeResourcePaths = true has no effect — the core gates that rebase on resource.is_shipped() (html.cpp:255-278), and a document resource is returned untouched. Mounting the service at the server root is impossible — HttpServer::prefix_pattern is ([a-zA-Z0-9_-]+), which rejects an empty prefix, and every route is nested under /file/<prefix>. embedImages = true does work, at the cost of base64 in memory on image-heavy files.
The bug is core-side, and not app-specific: the ooxml engines name an internal image by its absolute container path while odf names it relative, and the html layer emits whatever it is given. HtmlService::bring_offline throws not a relative path on the same input, so translate --embed-images=false on a docx fails outright. Fixed by opendocument-app/OpenDocument.core#727, which makes the emitted location relative to the document for every engine. This issue closes when the app picks up that release; embedImages = true is the workaround until then.
Repro
Any of these from the public corpus, all with --filter on the sweep tool or just opened by hand:
docx/file-sample_100kB.docx (also _500kB, _1MB)
docx/physics.docx
docx/sample2.docx, sample3.docx, sample4.docx
xlsx/sample.xlsx
Note
These lines arrived in #515, the odrcore JNI bindings migration, so this looks like an unintended regression rather than a deliberate setting.
Two things are separate from this and not fixed by it: the core also emits src="" for a few images (4 of 219 documents in its own reference output), and vector images (SVM/WMF) show the same placeholder for their own reasons.
Every image in a
.docx/.xlsxdocument comes out as the core's broken-image placeholder. ODF documents are fine, which is what makes it easy to miss.Found by sweeping OpenDocument.core's input corpus on a Pixel 9 Pro (#550). Roughly 23 of 225 documents are affected — every OOXML file in the corpus that contains an image.
Cause
CoreLoaderpublishes the translated document on the core's http server under/file/<prefix>/, but asks for absolute resource paths:https://github.com/opendocument-app/OpenDocument.droid/blob/main/app/src/main/java/app/opendocument/droid/background/CoreLoader.kt#L209-L212
For OOXML the core then emits the path as it appears in the container, rooted:
The WebView resolves that against the server root, not against
/file/odr/, so it misses either way. Both 404 (checked against the running app overadb forward):ODF documents work because the core emits their paths relative, and those resolve under the service mount point:
So the server serves document resources correctly; only the absolute form misses.
Neither of the two settings that look like the fix is one.
relativeResourcePaths = truehas no effect — the core gates that rebase onresource.is_shipped()(html.cpp:255-278), and a document resource is returned untouched. Mounting the service at the server root is impossible —HttpServer::prefix_patternis([a-zA-Z0-9_-]+), which rejects an empty prefix, and every route is nested under/file/<prefix>.embedImages = truedoes work, at the cost of base64 in memory on image-heavy files.The bug is core-side, and not app-specific: the ooxml engines name an internal image by its absolute container path while odf names it relative, and the html layer emits whatever it is given.
HtmlService::bring_offlinethrowsnot a relative pathon the same input, sotranslate --embed-images=falseon a docx fails outright. Fixed by opendocument-app/OpenDocument.core#727, which makes the emitted location relative to the document for every engine. This issue closes when the app picks up that release;embedImages = trueis the workaround until then.Repro
Any of these from the public corpus, all with
--filteron the sweep tool or just opened by hand:docx/file-sample_100kB.docx(also_500kB,_1MB)docx/physics.docxdocx/sample2.docx,sample3.docx,sample4.docxxlsx/sample.xlsxNote
These lines arrived in #515, the odrcore JNI bindings migration, so this looks like an unintended regression rather than a deliberate setting.
Two things are separate from this and not fixed by it: the core also emits
src=""for a few images (4 of 219 documents in its own reference output), and vector images (SVM/WMF) show the same placeholder for their own reasons.