feat: support TIFF images in DOCX rendering#2284
Conversation
|
Status: PASS The spec-relevant parts of this PR are clean. The core OOXML concern here is the The rest of the changes are runtime behavior — TIFF→PNG conversion in the browser, refactoring A few non-spec observations worth mentioning:
|
TIFF images in DOCX files rendered as broken icons because browsers cannot natively display image/tiff. Convert TIFF to PNG at import time using utif2, following the existing EMF/WMF → SVG conversion pattern. Closes #2064
Reject TIFF images exceeding 100M pixels before allocating RGBA buffers or canvas, preventing a malicious TIFF with extreme dimensions from freezing or crashing the tab during import.
Move MAX_PIXEL_COUNT check before UTIF.decodeImage/toRGBA8 so oversized TIFFs are rejected before allocating the RGBA buffer. Map .tif extension to image/tiff in Content_Types.xml generation to avoid emitting the invalid MIME type image/tif.
UTIF.decode populates raw tag entries (t256/t257) but .width/.height are only set after decodeImage. Read from raw tags so the pixel limit guard works before the expensive decode step without rejecting valid files.
- Use mimeTypeForExt mapping for .tif data URIs (image/tiff not image/tif) - Remove unused size arg from convertTiffToPng call - Add happy-path test asserting valid TIFF produces PNG data URI
- Remove unused Uint8Array/ArrayBufferView branches (only strings are passed) - Add handleImageNode test verifying convertTiffToPng is called for .tif files
Adds a Playwright test that loads a minimal DOCX containing a TIFF image and verifies the full pipeline: DocxZipper → convertTiffToPng → rendered PNG.
… constants Replace unmaintained utif2 with actively maintained image-js/tiff for TIFF decoding. Extract duplicated IMAGE_EXTS and MIME_TYPE_FOR_EXT mappings in DocxZipper.js to module-level constants.
Use decode(buffer, { ignoreImageData: true }) to check dimensions
before allocating pixel data, preventing DoS from small compressed
TIFFs with huge dimensions. Normalize Uint16Array and Float32Array
pixel data to 8-bit for canvas compatibility.
…red dataUriToArrayBuffer helper Address remaining PR review feedback: add tests for .tif → image/tiff MIME mapping (import data URI and export Content_Types), TIFF conversion failure fallback alt text, greyscale/grey+alpha/Uint16/Float32 toRGBA branches, and extract duplicate data-URI-stripping logic from metafile-converter and tiff-converter into shared dataUriToArrayBuffer in helpers.js.
image-js/tiff lacks support for PackBits, JPEG, and CCITT compression formats commonly found in Word documents. utif2 handles all TIFF compression types via its toRGBA8 pipeline. Updated tests to match utif2 API (decode → decodeImage → toRGBA8).
- createCanvas() now checks domEnvironment first, fixing silent failures in JSDOM environments where global document lacks canvas support - Add dataUriToArrayBuffer unit tests covering all input branches and both throw paths - Add explanatory comment for query-string module re-imports in tests
419d3bf to
1f0dcc5
Compare
|
🎉 This PR is included in superdoc v1.18.0-next.7 The release is available on GitHub release |
|
🎉 This PR is included in superdoc-cli v0.2.0-next.78 The release is available on GitHub release |
Summary
utif2, since browsers cannot render TIFF nativelyoriginalSrc/originalExtensionattributes.tif→image/tiffMIME mapping in DocxZipperdataUriToArrayBufferhelper extracted tohelpers.jsTest plan
tiff-converter.js(14 tests: decode pipeline, dimension guard, edge cases)DocxZipper.js(TIFF MIME mapping)encode-image-node-helpers.js(TIFF routing and fallback)load-doc-with-tiff.spec.ts(E2E import + PNG verification)Based on the original implementation by @gpardhivvarma in #2193.