mirror of
https://github.com/openseadragon/openseadragon.git
synced 2025-03-31 12:26:12 +03:00
Remove check for filetype based on uri or mimetype strings (maybe the filetype is not known before actually downloading the resource).
290 lines
8.6 KiB
JavaScript
290 lines
8.6 KiB
JavaScript
/*
|
|
* OpenSeadragon - LegacyTileSource
|
|
*
|
|
* Copyright (C) 2009 CodePlex Foundation
|
|
* Copyright (C) 2010-2013 OpenSeadragon contributors
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* - Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* - Neither the name of CodePlex Foundation nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
(function( $ ){
|
|
|
|
/**
|
|
* @class LegacyTileSource
|
|
* @classdesc The LegacyTileSource allows simple, traditional image pyramids to be loaded
|
|
* into an OpenSeadragon Viewer. Basically, this translates to the historically
|
|
* common practice of starting with a 'master' image, maybe a tiff for example,
|
|
* and generating a set of 'service' images like one or more thumbnails, a medium
|
|
* resolution image and a high resolution image in standard web formats like
|
|
* png or jpg.
|
|
*
|
|
* @memberof OpenSeadragon
|
|
* @extends OpenSeadragon.TileSource
|
|
* @param {Array} levels An array of file descriptions, each is an object with
|
|
* a 'url', a 'width', and a 'height'. Overriding classes can expect more
|
|
* properties but these properties are sufficient for this implementation.
|
|
* Additionally, the levels are required to be listed in order from
|
|
* smallest to largest.
|
|
* @property {Number} aspectRatio
|
|
* @property {Number} dimensions
|
|
* @property {Number} tileSize
|
|
* @property {Number} tileOverlap
|
|
* @property {Number} minLevel
|
|
* @property {Number} maxLevel
|
|
* @property {Array} levels
|
|
*/
|
|
$.LegacyTileSource = function( levels ) {
|
|
|
|
var options,
|
|
width,
|
|
height;
|
|
|
|
if( $.isArray( levels ) ){
|
|
options = {
|
|
type: 'legacy-image-pyramid',
|
|
levels: levels
|
|
};
|
|
}
|
|
|
|
//clean up the levels to make sure we support all formats
|
|
options.levels = filterFiles( options.levels );
|
|
|
|
if ( options.levels.length > 0 ) {
|
|
width = options.levels[ options.levels.length - 1 ].width;
|
|
height = options.levels[ options.levels.length - 1 ].height;
|
|
}
|
|
else {
|
|
width = 0;
|
|
height = 0;
|
|
$.console.error( "No supported image formats found" );
|
|
}
|
|
|
|
$.extend( true, options, {
|
|
width: width,
|
|
height: height,
|
|
tileSize: Math.max( height, width ),
|
|
tileOverlap: 0,
|
|
minLevel: 0,
|
|
maxLevel: options.levels.length > 0 ? options.levels.length - 1 : 0
|
|
} );
|
|
|
|
$.TileSource.apply( this, [ options ] );
|
|
|
|
this.levels = options.levels;
|
|
};
|
|
|
|
$.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.LegacyTileSource.prototype */{
|
|
/**
|
|
* Determine if the data and/or url imply the image service is supported by
|
|
* this tile source.
|
|
* @function
|
|
* @param {Object|Array} data
|
|
* @param {String} optional - url
|
|
*/
|
|
supports: function( data, url ){
|
|
return (
|
|
data.type &&
|
|
"legacy-image-pyramid" == data.type
|
|
) || (
|
|
data.documentElement &&
|
|
"legacy-image-pyramid" == data.documentElement.getAttribute('type')
|
|
);
|
|
},
|
|
|
|
|
|
/**
|
|
*
|
|
* @function
|
|
* @param {Object|XMLDocument} configuration - the raw configuration
|
|
* @param {String} dataUrl - the url the data was retreived from if any.
|
|
* @return {Object} options - A dictionary of keyword arguments sufficient
|
|
* to configure this tile sources constructor.
|
|
*/
|
|
configure: function( configuration, dataUrl ){
|
|
|
|
var options;
|
|
|
|
if( !$.isPlainObject(configuration) ){
|
|
|
|
options = configureFromXML( this, configuration );
|
|
|
|
}else{
|
|
|
|
options = configureFromObject( this, configuration );
|
|
}
|
|
|
|
return options;
|
|
|
|
},
|
|
|
|
/**
|
|
* @function
|
|
* @param {Number} level
|
|
*/
|
|
getLevelScale: function ( level ) {
|
|
var levelScale = NaN;
|
|
if ( this.levels.length > 0 && level >= this.minLevel && level <= this.maxLevel ) {
|
|
levelScale =
|
|
this.levels[ level ].width /
|
|
this.levels[ this.maxLevel ].width;
|
|
}
|
|
return levelScale;
|
|
},
|
|
|
|
/**
|
|
* @function
|
|
* @param {Number} level
|
|
*/
|
|
getNumTiles: function( level ) {
|
|
var scale = this.getLevelScale( level );
|
|
if ( scale ){
|
|
return new $.Point( 1, 1 );
|
|
} else {
|
|
return new $.Point( 0, 0 );
|
|
}
|
|
},
|
|
|
|
/**
|
|
* This method is not implemented by this class other than to throw an Error
|
|
* announcing you have to implement it. Because of the variety of tile
|
|
* server technologies, and various specifications for building image
|
|
* pyramids, this method is here to allow easy integration.
|
|
* @function
|
|
* @param {Number} level
|
|
* @param {Number} x
|
|
* @param {Number} y
|
|
* @throws {Error}
|
|
*/
|
|
getTileUrl: function ( level, x, y ) {
|
|
var url = null;
|
|
if ( this.levels.length > 0 && level >= this.minLevel && level <= this.maxLevel ) {
|
|
url = this.levels[ level ].url;
|
|
}
|
|
return url;
|
|
}
|
|
} );
|
|
|
|
/**
|
|
* This method removes any files from the Array which dont conform to our
|
|
* basic requirements for a 'level' in the LegacyTileSource.
|
|
* @private
|
|
* @inner
|
|
* @function
|
|
*/
|
|
function filterFiles( files ){
|
|
var filtered = [],
|
|
file,
|
|
i;
|
|
for( i = 0; i < files.length; i++ ){
|
|
file = files[ i ];
|
|
if( file.height &&
|
|
file.width &&
|
|
file.url ){
|
|
//This is sufficient to serve as a level
|
|
filtered.push({
|
|
url: file.url,
|
|
width: Number( file.width ),
|
|
height: Number( file.height )
|
|
});
|
|
}
|
|
else {
|
|
$.console.error( 'Unsupported image format: %s', file.url ? file.url : '<no URL>' );
|
|
}
|
|
}
|
|
|
|
return filtered.sort(function(a,b){
|
|
return a.height - b.height;
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* @inner
|
|
* @function
|
|
*/
|
|
function configureFromXML( tileSource, xmlDoc ){
|
|
|
|
if ( !xmlDoc || !xmlDoc.documentElement ) {
|
|
throw new Error( $.getString( "Errors.Xml" ) );
|
|
}
|
|
|
|
var root = xmlDoc.documentElement,
|
|
rootName = root.tagName,
|
|
conf = null,
|
|
levels = [],
|
|
level,
|
|
i;
|
|
|
|
if ( rootName == "image" ) {
|
|
|
|
try {
|
|
conf = {
|
|
type: root.getAttribute( "type" ),
|
|
levels: []
|
|
};
|
|
|
|
levels = root.getElementsByTagName( "level" );
|
|
for ( i = 0; i < levels.length; i++ ) {
|
|
level = levels[ i ];
|
|
|
|
conf.levels .push({
|
|
url: level.getAttribute( "url" ),
|
|
width: parseInt( level.getAttribute( "width" ), 10 ),
|
|
height: parseInt( level.getAttribute( "height" ), 10 )
|
|
});
|
|
}
|
|
|
|
return configureFromObject( tileSource, conf );
|
|
|
|
} catch ( e ) {
|
|
throw (e instanceof Error) ?
|
|
e :
|
|
new Error( 'Unknown error parsing Legacy Image Pyramid XML.' );
|
|
}
|
|
} else if ( rootName == "collection" ) {
|
|
throw new Error( 'Legacy Image Pyramid Collections not yet supported.' );
|
|
} else if ( rootName == "error" ) {
|
|
throw new Error( 'Error: ' + xmlDoc );
|
|
}
|
|
|
|
throw new Error( 'Unknown element ' + rootName );
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* @inner
|
|
* @function
|
|
*/
|
|
function configureFromObject( tileSource, configuration ){
|
|
|
|
return configuration.levels;
|
|
|
|
}
|
|
|
|
}( OpenSeadragon ));
|