Merge pull request #9743 from lutzhelm/iiif-v3beta
Finalize IIIF Image API version 3
This commit is contained in:
+20
-11
@@ -94,6 +94,8 @@ import {assert} from '../asserts.js';
|
|||||||
* image service additional to the ones indicated by the compliance level.
|
* image service additional to the ones indicated by the compliance level.
|
||||||
* @property {Array<string>} [extraFeatures] Additional supported features whose support
|
* @property {Array<string>} [extraFeatures] Additional supported features whose support
|
||||||
* is not indicated by the compliance level.
|
* is not indicated by the compliance level.
|
||||||
|
* @property {Array<string>} [preferredFormats] Image formats that should preferrably
|
||||||
|
* be used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -156,15 +158,15 @@ IIIF_PROFILE_VALUES[Versions.VERSION3] = {
|
|||||||
qualities: ['default']
|
qualities: ['default']
|
||||||
},
|
},
|
||||||
'level1': {
|
'level1': {
|
||||||
supports: ['regionByPx', 'regionSquare', 'sizeByW', 'sizeByH'],
|
supports: ['regionByPx', 'regionSquare', 'sizeByW', 'sizeByH', 'sizeByWh'],
|
||||||
formats: ['jpg'],
|
formats: ['jpg'],
|
||||||
qualities: ['default']
|
qualities: ['default']
|
||||||
},
|
},
|
||||||
'level2': {
|
'level2': {
|
||||||
supports: ['regionByPx', 'regionSquare', 'regionByPct',
|
supports: ['regionByPx', 'regionSquare', 'regionByPct',
|
||||||
'sizeByW', 'sizeByH', 'sizeByPct', 'sizeByConfinedWh', 'sizeByWh'],
|
'sizeByW', 'sizeByH', 'sizeByPct', 'sizeByConfinedWh', 'sizeByWh'],
|
||||||
formats: ['jpg'],
|
formats: ['jpg', 'png'],
|
||||||
qualities: ['default', 'bitonal']
|
qualities: ['default']
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
IIIF_PROFILE_VALUES['none'] = {
|
IIIF_PROFILE_VALUES['none'] = {
|
||||||
@@ -231,7 +233,16 @@ function generateVersion2Options(iiifInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function generateVersion3Options(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 {
|
return {
|
||||||
url: iiifInfo.imageInfo['id'],
|
url: iiifInfo.imageInfo['id'],
|
||||||
sizes: iiifInfo.imageInfo.sizes === undefined ? undefined : iiifInfo.imageInfo.sizes.map(function(size) {
|
sizes: iiifInfo.imageInfo.sizes === undefined ? undefined : iiifInfo.imageInfo.sizes.map(function(size) {
|
||||||
@@ -251,13 +262,10 @@ function generateVersion3Options(iiifInfo) {
|
|||||||
})[0],
|
})[0],
|
||||||
supports: iiifInfo.imageInfo.extraFeatures === undefined ? levelProfile.supports :
|
supports: iiifInfo.imageInfo.extraFeatures === undefined ? levelProfile.supports :
|
||||||
[...levelProfile.supports, ...iiifInfo.imageInfo.extraFeatures],
|
[...levelProfile.supports, ...iiifInfo.imageInfo.extraFeatures],
|
||||||
formats: iiifInfo.imageInfo.extraFormats === undefined ? levelProfile.formats :
|
formats: formats,
|
||||||
[...levelProfile.formats, ...iiifInfo.imageInfo.extraFormats],
|
|
||||||
qualities: iiifInfo.imageInfo.extraQualities === undefined ? levelProfile.qualities :
|
qualities: iiifInfo.imageInfo.extraQualities === undefined ? levelProfile.qualities :
|
||||||
[...levelProfile.supports, ...iiifInfo.imageInfo.extraQualities],
|
[...levelProfile.qualities, ...iiifInfo.imageInfo.extraQualities],
|
||||||
maxWidth: undefined,
|
preferredFormat: preferredFormat
|
||||||
maxHeight: undefined,
|
|
||||||
maxArea: undefined
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +422,8 @@ class IIIFInfo {
|
|||||||
version: version,
|
version: version,
|
||||||
size: [this.imageInfo.width, this.imageInfo.height],
|
size: [this.imageInfo.width, this.imageInfo.height],
|
||||||
sizes: imageOptions.sizes,
|
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,
|
supports: imageOptions.supports,
|
||||||
quality: options.quality && imageOptions.qualities.includes(options.quality) ?
|
quality: options.quality && imageOptions.qualities.includes(options.quality) ?
|
||||||
options.quality : imageOptions.qualities.includes('native') ? 'native' : 'default',
|
options.quality : imageOptions.qualities.includes('native') ? 'native' : 'default',
|
||||||
|
|||||||
@@ -219,7 +219,40 @@ describe('ol.format.IIIFInfo', function() {
|
|||||||
expect(level.supports).to.contain('sizeByDistortedWh');
|
expect(level.supports).to.contain('sizeByDistortedWh');
|
||||||
expect(level.supports).to.contain('sizeByWh');
|
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');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -290,7 +323,22 @@ describe('ol.format.IIIFInfo', function() {
|
|||||||
height: 1500,
|
height: 1500,
|
||||||
profile: ['http://iiif.io/api/image/2/level2.json']
|
profile: ['http://iiif.io/api/image/2/level2.json']
|
||||||
});
|
});
|
||||||
const options = iiifInfo.getTileSourceOptions({
|
let options = iiifInfo.getTileSourceOptions({
|
||||||
|
quality: 'bitonal',
|
||||||
|
format: 'png'
|
||||||
|
});
|
||||||
|
expect(options).to.have.property('quality', 'bitonal');
|
||||||
|
expect(options).to.have.property('format', 'png');
|
||||||
|
|
||||||
|
iiifInfo.setImageInfo({
|
||||||
|
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||||
|
'@id': 'http://iiif.test/version3/id',
|
||||||
|
width: 2000,
|
||||||
|
height: 1500,
|
||||||
|
profile: 'level2',
|
||||||
|
extraQualities: ['gray', 'bitonal']
|
||||||
|
});
|
||||||
|
options = iiifInfo.getTileSourceOptions({
|
||||||
quality: 'bitonal',
|
quality: 'bitonal',
|
||||||
format: 'png'
|
format: 'png'
|
||||||
});
|
});
|
||||||
@@ -308,7 +356,21 @@ describe('ol.format.IIIFInfo', function() {
|
|||||||
height: 1500,
|
height: 1500,
|
||||||
profile: ['http://iiif.io/api/image/2/level1.json']
|
profile: ['http://iiif.io/api/image/2/level1.json']
|
||||||
});
|
});
|
||||||
const options = iiifInfo.getTileSourceOptions({
|
let options = iiifInfo.getTileSourceOptions({
|
||||||
|
quality: 'bitonal',
|
||||||
|
format: 'png'
|
||||||
|
});
|
||||||
|
expect(options).to.have.property('quality', 'default');
|
||||||
|
expect(options).to.have.property('format', 'jpg');
|
||||||
|
|
||||||
|
iiifInfo.setImageInfo({
|
||||||
|
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||||
|
'@id': 'http://iiif.test/version3/id',
|
||||||
|
width: 2000,
|
||||||
|
height: 1500,
|
||||||
|
profile: 'level1'
|
||||||
|
});
|
||||||
|
options = iiifInfo.getTileSourceOptions({
|
||||||
quality: 'bitonal',
|
quality: 'bitonal',
|
||||||
format: 'png'
|
format: 'png'
|
||||||
});
|
});
|
||||||
@@ -350,7 +412,8 @@ describe('ol.format.IIIFInfo', function() {
|
|||||||
expect(options.supports).to.contain('regionSquare');
|
expect(options.supports).to.contain('regionSquare');
|
||||||
expect(options.supports).to.contain('sizeByW');
|
expect(options.supports).to.contain('sizeByW');
|
||||||
expect(options.supports).to.contain('sizeByH');
|
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);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -448,6 +511,26 @@ describe('ol.format.IIIFInfo', function() {
|
|||||||
expect(options.tileSize[0]).to.be(512);
|
expect(options.tileSize[0]).to.be(512);
|
||||||
expect(options.tileSize[1]).to.be(1024);
|
expect(options.tileSize[1]).to.be(1024);
|
||||||
|
|
||||||
|
iiifInfo.setImageInfo({
|
||||||
|
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||||
|
'@id': 'http://iiif.test/id',
|
||||||
|
profile: 'level0',
|
||||||
|
tiles: [{
|
||||||
|
scaleFactors: [1, 2, 4, 8],
|
||||||
|
width: 512,
|
||||||
|
height: 256
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
options = iiifInfo.getTileSourceOptions();
|
||||||
|
expect(options.resolutions).to.have.length(4);
|
||||||
|
expect(options.resolutions).to.contain(1);
|
||||||
|
expect(options.resolutions).to.contain(2);
|
||||||
|
expect(options.resolutions).to.contain(4);
|
||||||
|
expect(options.resolutions).to.contain(8);
|
||||||
|
expect(options.tileSize).to.have.length(2);
|
||||||
|
expect(options.tileSize[0]).to.be(512);
|
||||||
|
expect(options.tileSize[1]).to.be(256);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -470,7 +553,7 @@ describe('ol.format.IIIFInfo', function() {
|
|||||||
height: 250
|
height: 250
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
const options = iiifInfo.getTileSourceOptions();
|
let options = iiifInfo.getTileSourceOptions();
|
||||||
expect(options.sizes).to.have.length(3);
|
expect(options.sizes).to.have.length(3);
|
||||||
expect(options.sizes[0]).to.have.length(2);
|
expect(options.sizes[0]).to.have.length(2);
|
||||||
expect(options.sizes[0][0]).to.be(2000);
|
expect(options.sizes[0][0]).to.be(2000);
|
||||||
@@ -482,6 +565,62 @@ describe('ol.format.IIIFInfo', function() {
|
|||||||
expect(options.sizes[2][0]).to.be(500);
|
expect(options.sizes[2][0]).to.be(500);
|
||||||
expect(options.sizes[2][1]).to.be(250);
|
expect(options.sizes[2][1]).to.be(250);
|
||||||
|
|
||||||
|
iiifInfo.setImageInfo({
|
||||||
|
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||||
|
'@id': 'http://iiif.test/id',
|
||||||
|
'sizes': [{
|
||||||
|
width: 1500,
|
||||||
|
height: 800
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
options = iiifInfo.getTileSourceOptions();
|
||||||
|
expect(options.sizes).to.have.length(1);
|
||||||
|
expect(options.sizes[0]).to.have.length(2);
|
||||||
|
expect(options.sizes[0][0]).to.be(1500);
|
||||||
|
expect(options.sizes[0][1]).to.be(800);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -201,6 +201,21 @@ describe('ol.source.IIIF', function() {
|
|||||||
expect(tileUrlFunction([2, 0, 0])).to.be('http://iiif.test/image-id/full/full/0/default.jpg');
|
expect(tileUrlFunction([2, 0, 0])).to.be('http://iiif.test/image-id/full/full/0/default.jpg');
|
||||||
expect(tileUrlFunction([3, 0, 0])).to.be(undefined);
|
expect(tileUrlFunction([3, 0, 0])).to.be(undefined);
|
||||||
|
|
||||||
|
tileUrlFunction = getSource({
|
||||||
|
version: Versions.VERSION3,
|
||||||
|
sizes: [[2000, 1500], [1000, 750], [500, 375]]
|
||||||
|
}).getTileUrlFunction();
|
||||||
|
|
||||||
|
expect(tileUrlFunction([0, 0, 0])).to.be('http://iiif.test/image-id/full/500,375/0/default.jpg');
|
||||||
|
expect(tileUrlFunction([1, 0, 0])).to.be('http://iiif.test/image-id/full/1000,750/0/default.jpg');
|
||||||
|
expect(tileUrlFunction([2, 0, 0])).to.be('http://iiif.test/image-id/full/max/0/default.jpg');
|
||||||
|
expect(tileUrlFunction([3, 0, 0])).to.be(undefined);
|
||||||
|
expect(tileUrlFunction([-1, 0, 0])).to.be(undefined);
|
||||||
|
expect(tileUrlFunction([0, 1, 0])).to.be(undefined);
|
||||||
|
expect(tileUrlFunction([0, 0, 1])).to.be(undefined);
|
||||||
|
expect(tileUrlFunction([1, 1, 0])).to.be(undefined);
|
||||||
|
expect(tileUrlFunction([1, 0, 1])).to.be(undefined);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cannot provide scaled tiles without provided tilesize or supported features', function() {
|
it('cannot provide scaled tiles without provided tilesize or supported features', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user