Skip to content

feat: add client-side TIFF previewer using UTIF.js#3646

Merged
luis100 merged 1 commit intodevelopmentfrom
claude/tiff-viewer
Apr 16, 2026
Merged

feat: add client-side TIFF previewer using UTIF.js#3646
luis100 merged 1 commit intodevelopmentfrom
claude/tiff-viewer

Conversation

@luis100
Copy link
Copy Markdown
Member

@luis100 luis100 commented Apr 14, 2026

Summary

  • Add TiffViewer.java GWT widget that fetches TIFF files via XHR (arraybuffer) and renders each page onto an HTML5 <canvas> using UTIF.js, stacked vertically like the PDF.js viewer
  • Wire TiffViewer into BitstreamPreview dispatch (new viewer type "tiff")
  • Bundle UTIF.js 3.1.0 as a static asset at js/utif/UTIF.js (no WebJar available on Maven Central); include script tag in both Main.html and Portal.html
  • Register TIFF viewer in roda-wui.properties: mimetypes image/tiff / image/x-tiff, extensions .tif / .tiff, PRONOM IDs fmt/7–fmt/10, fmt/154–fmt/159, fmt/353 (GeoTIFF)
  • Fix spring.web.resources.static-locations property name in application.properties (Spring Boot 3 renamed spring.resources.*)
  • Fix GWT debug-* profiles in pom.xml: add <webappDirectory> pointing to target/<finalName>/static/ so compiled JS lands where Spring Boot resolves classpath:/static/

Security

UTIF.js was reviewed for vulnerabilities. All risks are DoS-class (not XSS/RCE). Guards applied in TiffViewer:

  • MAX_PAGES = 500 — prevents memory exhaustion from files with thousands of IFDs
  • MAX_DIMENSION_PX = 16384 — skips any page whose width or height exceeds 16 384 px (1 GiB RGBA buffer limit)
  • All UTIF calls wrapped in try/catch; errors render a plain message instead of crashing

Test plan

  • Single-page TIFF renders correctly in the bitstream preview panel
  • Multi-page TIFF renders all pages stacked vertically with page labels (e.g. "1 / 5")
  • TIFF files are matched by PRONOM ID, mimetype, and file extension
  • Oversized or malformed TIFF shows an error message without crashing the browser tab
  • GWT compiles cleanly with -Pdebug-main and Spring Boot serves the module JS without NoResourceFoundException

🤖 Generated with Claude Code

  Renders single- and multi-page TIFF files directly in the browser via
  HTML5 canvas without server-side conversion. Pages are stacked vertically
  matching the PDF.js layout.

  - Add TiffViewer.java GWT widget (JSNI XHR + UTIF.decode/toRGBA8/canvas)
  - Wire TiffViewer into BitstreamPreview dispatch for viewer type "tiff"
  - Bundle UTIF.js 3.1.0 as a static asset under js/utif/
  - Include UTIF.js in Main.html and Portal.html
  - Register TIFF viewer in roda-wui.properties (mimetypes, extensions,
    PRONOM IDs fmt/7-fmt/10, fmt/154-fmt/159, fmt/353 / GeoTIFF)
  - Fix spring.web.resources.static-locations property name in
    application.properties (SB3 renamed spring.resources.*)
  - Fix GWT debug-profile pom.xml: add webappDirectory pointing to
    target/<finalName>/static so compiled JS lands where Spring Boot
    can serve it from classpath:/static/

  Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. feature request labels Apr 14, 2026
@luis100 luis100 changed the base branch from master to development April 14, 2026 09:35
@luis100 luis100 requested a review from hmiguim April 14, 2026 10:04
luis100 added a commit that referenced this pull request Apr 16, 2026
- Remove VIEWER_TYPE_TIFF and tiffPreview() leaked from PR #3646
  (caused compilation failure: TiffViewer class not on this branch)
- Escape error message before innerHTML insertion to prevent XSS
- Move escapeHtml before onError so it is defined at call site
- Remove redundant FORBID_ATTR list from DOMPurify (already default behaviour)
- Track Blob object-URLs in instance field; revoke all on widget detach
  to prevent memory leak
- Update DOMPurify WebJar from 3.2.6 to 3.4.0 to fix Snyk findings
- Add CSS for email viewer classes to main.gss

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@luis100 luis100 added this to the 6.2.0 milestone Apr 16, 2026
@luis100 luis100 merged commit 78dd397 into development Apr 16, 2026
8 checks passed
@hmiguim hmiguim modified the milestones: 6.2.0, 6.1.0 Apr 17, 2026
@hmiguim hmiguim deleted the claude/tiff-viewer branch April 17, 2026 08:16
luis100 added a commit that referenced this pull request Apr 17, 2026
The UTIF.js <script> tag was polluted from the tiff-viewer branch into
this branch. js/utif/UTIF.js is not produced by the email-viewer build,
causing a 404 / NoResourceFoundException on every page load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
luis100 added a commit that referenced this pull request Apr 17, 2026
- Remove VIEWER_TYPE_TIFF and tiffPreview() leaked from PR #3646
  (caused compilation failure: TiffViewer class not on this branch)
- Escape error message before innerHTML insertion to prevent XSS
- Move escapeHtml before onError so it is defined at call site
- Remove redundant FORBID_ATTR list from DOMPurify (already default behaviour)
- Track Blob object-URLs in instance field; revoke all on widget detach
  to prevent memory leak
- Update DOMPurify WebJar from 3.2.6 to 3.4.0 to fix Snyk findings
- Add CSS for email viewer classes to main.gss

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
luis100 added a commit that referenced this pull request Apr 17, 2026
…elopment

After rebasing claude/email-viewer onto origin/development (which had
merged PR #3646 with TIFF viewer support), the earlier fix commit that
removed TIFF constants/methods as pollution still applied, causing
compilation errors. Restore them so the preview dispatch works correctly
for both TIFF and email viewers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants