From cc976dd4add9eb0e68b3a5b5ebaa1f4fea4ed262 Mon Sep 17 00:00:00 2001 From: Lutz Helm Date: Mon, 1 Jul 2019 17:51:52 +0200 Subject: [PATCH] Adjust IIIF info parsing to 3.0-beta spec - respect `preferredFormats` - correct compliance level profile formats and features --- src/ol/format/IIIFInfo.js | 26 ++++++++--- test/spec/ol/format/iiif.test.js | 80 +++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/src/ol/format/IIIFInfo.js b/src/ol/format/IIIFInfo.js index 73e1834fba..499e9fc4d8 100644 --- a/src/ol/format/IIIFInfo.js +++ b/src/ol/format/IIIFInfo.js @@ -94,6 +94,8 @@ import {assert} from '../asserts.js'; * image service additional to the ones indicated by the compliance level. * @property {Array} [extraFeatures] Additional supported features whose support * is not indicated by the compliance level. + * @property {Array} [preferredFormats] Image formats that should preferrably + * be used. */ /** @@ -156,15 +158,15 @@ IIIF_PROFILE_VALUES[Versions.VERSION3] = { qualities: ['default'] }, 'level1': { - supports: ['regionByPx', 'regionSquare', 'sizeByW', 'sizeByH'], + supports: ['regionByPx', 'regionSquare', 'sizeByW', 'sizeByH', 'sizeByWh'], formats: ['jpg'], qualities: ['default'] }, 'level2': { supports: ['regionByPx', 'regionSquare', 'regionByPct', 'sizeByW', 'sizeByH', 'sizeByPct', 'sizeByConfinedWh', 'sizeByWh'], - formats: ['jpg'], - qualities: ['default', 'bitonal'] + formats: ['jpg', 'png'], + qualities: ['default'] } }; IIIF_PROFILE_VALUES['none'] = { @@ -231,7 +233,16 @@ function generateVersion2Options(iiifInfo) { } function generateVersion3Options(iiifInfo) { - const levelProfile = iiifInfo.getComplianceLevelSupportedFeatures(); + const levelProfile = iiifInfo.getComplianceLevelSupportedFeatures(), + formats = iiifInfo.imageInfo.extraFormats === undefined ? levelProfile.formats : + [...levelProfile.formats, ...iiifInfo.imageInfo.extraFormats], + preferredFormat = iiifInfo.imageInfo.preferredFormats !== undefined && Array.isArray(iiifInfo.imageInfo.preferredFormats) && + iiifInfo.imageInfo.preferredFormats.length > 0 ? + iiifInfo.imageInfo.preferredFormats.filter(function(format) { + return ['jpg', 'png', 'gif'].includes(format); + }).reduce(function(acc, format) { + return acc === undefined && formats.includes(format) ? format : acc; + }, undefined) : undefined; return { url: iiifInfo.imageInfo['id'], sizes: iiifInfo.imageInfo.sizes === undefined ? undefined : iiifInfo.imageInfo.sizes.map(function(size) { @@ -251,10 +262,10 @@ function generateVersion3Options(iiifInfo) { })[0], supports: iiifInfo.imageInfo.extraFeatures === undefined ? levelProfile.supports : [...levelProfile.supports, ...iiifInfo.imageInfo.extraFeatures], - formats: iiifInfo.imageInfo.extraFormats === undefined ? levelProfile.formats : - [...levelProfile.formats, ...iiifInfo.imageInfo.extraFormats], + formats: formats, qualities: iiifInfo.imageInfo.extraQualities === undefined ? levelProfile.qualities : [...levelProfile.supports, ...iiifInfo.imageInfo.extraQualities], + preferredFormat: preferredFormat, maxWidth: undefined, maxHeight: undefined, maxArea: undefined @@ -414,7 +425,8 @@ class IIIFInfo { version: version, size: [this.imageInfo.width, this.imageInfo.height], sizes: imageOptions.sizes, - format: imageOptions.formats.includes(options.format) ? options.format : 'jpg', + format: options.format !== undefined && imageOptions.formats.includes(options.format) ? options.format : + imageOptions.preferredFormat !== undefined ? imageOptions.preferredFormat : 'jpg', supports: imageOptions.supports, quality: options.quality && imageOptions.qualities.includes(options.quality) ? options.quality : imageOptions.qualities.includes('native') ? 'native' : 'default', diff --git a/test/spec/ol/format/iiif.test.js b/test/spec/ol/format/iiif.test.js index 49f14fe561..debce651b5 100644 --- a/test/spec/ol/format/iiif.test.js +++ b/test/spec/ol/format/iiif.test.js @@ -219,7 +219,40 @@ describe('ol.format.IIIFInfo', function() { expect(level.supports).to.contain('sizeByDistortedWh'); expect(level.supports).to.contain('sizeByWh'); - // TODO test version 3 compliance level features once version 3 is final + iiifInfo.setImageInfo({ + '@context': 'http://iiif.io/api/image/3/context.json', + profile: 'level0' + }); + level = iiifInfo.getComplianceLevelSupportedFeatures(); + expect(level.supports).to.be.empty(); + + iiifInfo.setImageInfo({ + '@context': 'http://iiif.io/api/image/3/context.json', + profile: 'level1' + }); + level = iiifInfo.getComplianceLevelSupportedFeatures(); + expect(level.supports).to.have.length(5); + expect(level.supports).to.contain('regionByPx'); + expect(level.supports).to.contain('regionSquare'); + expect(level.supports).to.contain('sizeByW'); + expect(level.supports).to.contain('sizeByH'); + expect(level.supports).to.contain('sizeByWh'); + + iiifInfo.setImageInfo({ + '@context': 'http://iiif.io/api/image/3/context.json', + profile: 'level2' + }); + level = iiifInfo.getComplianceLevelSupportedFeatures(); + expect(level.supports).to.have.length(8); + expect(level.supports).to.contain('regionByPx'); + expect(level.supports).to.contain('regionByPct'); + expect(level.supports).to.contain('regionSquare'); + expect(level.supports).to.contain('sizeByW'); + expect(level.supports).to.contain('sizeByH'); + expect(level.supports).to.contain('sizeByWh'); + expect(level.supports).to.contain('sizeByConfinedWh'); + expect(level.supports).to.contain('sizeByPct'); + }); }); @@ -350,7 +383,8 @@ describe('ol.format.IIIFInfo', function() { expect(options.supports).to.contain('regionSquare'); expect(options.supports).to.contain('sizeByW'); expect(options.supports).to.contain('sizeByH'); - expect(options.supports).to.have.length(6); + expect(options.supports).to.contain('sizeByWh'); + expect(options.supports).to.have.length(7); }); @@ -484,4 +518,46 @@ describe('ol.format.IIIFInfo', function() { }); + it('respects the preferred image formats', function() { + + iiifInfo.setImageInfo({ + '@context': 'http://iiif.io/api/image/3/context.json', + 'id': 'http://iiif.test/id', + 'profile': 'level0', + 'preferredFormats': ['png', 'gif'] + }); + let options = iiifInfo.getTileSourceOptions(); + expect(options.format).to.be('jpg'); + + iiifInfo.setImageInfo({ + '@context': 'http://iiif.io/api/image/3/context.json', + 'id': 'http://iiif.test/id', + 'profile': 'level1', + 'preferredFormats': ['png', 'gif'] + }); + options = iiifInfo.getTileSourceOptions(); + expect(options.format).to.be('jpg'); + + iiifInfo.setImageInfo({ + '@context': 'http://iiif.io/api/image/3/context.json', + 'id': 'http://iiif.test/id', + 'profile': 'level1', + 'extraFormats': ['webp', 'gif'], + 'preferredFormats': ['webp', 'png', 'gif'] + }); + options = iiifInfo.getTileSourceOptions(); + expect(options.format).to.be('gif'); + + iiifInfo.setImageInfo({ + '@context': 'http://iiif.io/api/image/3/context.json', + 'id': 'http://iiif.test/id', + 'profile': 'level2', + 'preferredFormats': ['png', 'gif'] + }); + options = iiifInfo.getTileSourceOptions(); + expect(options.format).to.be('png'); + + }); + + });