Skip to content

Support IIIF images with no Image API service#563

Closed
tacman wants to merge 2 commits into
DDMAL:developfrom
tacman:feature/optional-image-service
Closed

Support IIIF images with no Image API service#563
tacman wants to merge 2 commits into
DDMAL:developfrom
tacman:feature/optional-image-service

Conversation

@tacman

@tacman tacman commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Fixes #562.

Problem

v7 rejects otherwise-valid IIIF Presentation 3 manifests whose painting-annotation image bodies have no service (a plain static image with no Image API), reporting "Invalid IIIF response body." Static images without an Image API service are explicitly valid per the Presentation 3 spec.

Note on scope

develop already picked up the rism-digital/elm-iiif2.0.0 bump alone (832b8b9, released as 7.3.0). That's necessary but not sufficient: it stops the manifest decode from failing, but the image still doesn't render — OpenSeadragon gets handed a bare static-image URL as a tileSource string, tries to fetch it and parse it as an info.json/tile-descriptor document, and fails with No TileSource was able to open .... I verified this on develop as it stands today (build + browser check) before writing this PR.

This PR rebases on top of that and adds the rest: telling the viewer when a tile source is a plain static image so it opens it correctly.

Fix

  • Threads a new isStatic flag through diva.js's own model/view pipeline:
    • PageImage gains isStatic (True when image.service is empty).
    • The tileSourcesUpdated and filterPreviewUpdated Elm ports carry that flag alongside the URL.
    • viewer-element.ts/diva.ts open static images as {type: "image", url} (OpenSeadragon's plain-image source) instead of treating the URL as an info.json tile-pyramid endpoint.
    • Skips building an Image-API thumbnail derivative URL for static images (there's no Image API to request it from) — falls back to the full image URL.
  • Bumps package.json to 7.3.1 (7.3.0 is already published).

Tests

Added tests/ModelTest.elm (run via yarn test, using elm-test-rs) covering:

  • A painting image body with no service → decodes, and manifestToPages produces a PageImage flagged isStatic with the raw image URL as its tile source.
  • A painting image body with an Image API service → still resolves to an info.json tile source (no regression for the common case).
Running 2 tests.
TEST RUN PASSED
Passed:   2
Failed:   0

Also added a test.yml CI workflow to run yarn test and make build build-dev on push/PR.

Manual verification

Built (make build build-dev) and loaded testing/index.html in a browser, comparing current develop against this branch:

  • On develop as-is (elm-iiif 2.0.0 alone): a static-image manifest decodes and its thumbnail renders, but the main viewer stays blank with No TileSource was able to open ... console errors.
  • On this branch: the same manifest renders correctly in the main viewer — confirmed via network requests hitting the raw image URL directly with no info.json request.
  • The IIIF Cookbook's 0001 Simplest Manifest – Single Image (the exact repro from the issue) mounts correctly; its own image asset happens to lack CORS headers, which is a limitation of that specific fixture, not of the decoder.
  • A normal Image-API-backed manifest (Bodleian Library, multi-page) still renders and paginates correctly — no regression.

@ahankinson

Copy link
Copy Markdown
Member

Whoops... crossed wires. I just published 7.3.0, so this will have to go into 7.3.1. I upgraded the dependency so you can remove that from your PR.

@ahankinson

Copy link
Copy Markdown
Member

I think you will also need to build the release versions again after the bump to resolve the conflict.

The only hesitation I have is that you're using the full image as the thumbnails. I'm not sure what the answer is to that, but that's a significant load if you're downloading all the full resolution images for that purpose.

tacman added 2 commits July 3, 2026 11:45
Upgrade to elm-iiif 2.0.0, which decodes painting-annotation image
bodies that omit `service` (a plain static image, valid per the
Presentation 3 spec) instead of rejecting the manifest outright.

Thread that through diva.js's own pipeline: PageImage now carries an
isStatic flag, and the tileSourcesUpdated/filterPreviewUpdated ports
pass it to the viewer so OpenSeadragon opens static images as
{type: "image", url} instead of trying to fetch them as an info.json
tile pyramid. Also skip building an Image-API thumbnail derivative URL
for static images, since there's no Image API to request it from.

Add an elm-test suite covering both the static-image and
Image-API-backed cases, and a CI workflow to run it.
7.3.0 was already published with the minimal elm-iiif bump alone;
this patch adds the OpenSeadragon-side plumbing so static images
actually render (not just decode without crashing).
@tacman
tacman force-pushed the feature/optional-image-service branch from 753cb87 to 59237bc Compare July 3, 2026 15:47
@ahankinson

ahankinson commented Jul 3, 2026

Copy link
Copy Markdown
Member

@tacman any ideas about the thumbnails? Do you know what UV or Mirardor does in this case?

@tacman

tacman commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

I use imgproxy.net for thumbnails. iiif allows sending an array of different-size images, many sites provide thumbnails simply as an extra file, so i think finding an iiif manifest with thumbnails will work.

ahankinson added a commit to rism-digital/elm-iiif that referenced this pull request Jul 6, 2026
When canvases define their own thumbnails, prefer those over constructing one, or using a full image.

Refs DDMAL/diva.js#563
ahankinson added a commit that referenced this pull request Jul 6, 2026
Also fixes an issue where static thumbnails were not correctly supported, and thumbnails defined on canvases were also not supported.

Adds automated testing to github workflows.

co-authored by @tacman

Fixes #562
Replaces #563
@ahankinson

Copy link
Copy Markdown
Member

I reworked this PR into a new set of changes. For thumbnails, canvases now support the thumbnail property so you can set your imgproxy URL as a thumbnail on the canvas, instead of downloading the whole file.

I've tested it and it seems to work.

I'm going to close this PR unmerged because it's been superceded, but I've mentioned you as co-author on the commit message and in the release. Thanks again!

@ahankinson ahankinson closed this Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

v7 rejects valid Presentation 3 manifests with plain (service-less) image bodies

2 participants