diff --git a/app/models/projection.rb b/app/models/projection.rb index b8006281..d44886fb 100644 --- a/app/models/projection.rb +++ b/app/models/projection.rb @@ -112,7 +112,7 @@ def image_source end def real_transformation - return transformation unless image.is_a? RestrictedImage + return transformation unless (image.is_a? RestrictedImage) || use_original_size? IIIF::Image::Transformation.new( region: transformation.region, @@ -127,7 +127,7 @@ def restricted_size size = transformation.size case size when IIIF::Image::Size::BestFit - max_size = image.max_size(self) + max_size = max_image_size if size.width <= max_size.width && size.height <= max_size.height size else @@ -139,4 +139,25 @@ def restricted_size size end end + + # For a full image request, if the requested width and height are larger than the original image, + # this method will return true + def use_original_size? + size = transformation.size + max_size = image.max_tile_dimensions.call(self) + (size.is_a? IIIF::Image::Size::BestFit) && max_size.width < size.width && max_size.height < size.height + end + + # The original restricted image function used max_size, but the StacksImage class does not have that method + # Since we are using the restricted image block for both RestrictedImage and StacksImage, we check + # which method is available + def max_image_size + image.respond_to?(:max_size) ? image.max_size(self) : dimensions_to_size(image.max_tile_dimensions.call(self)) + end + + # StacksImage has max_tile_dimensions, which returns dimensions + # We need to create a Size object in order to pass back to create the Iiif image object for image_source + def dimensions_to_size(dimensions) + IIIF::Image::Size::BestFit.new(dimensions.width, dimensions.height) + end end diff --git a/spec/models/projection_spec.rb b/spec/models/projection_spec.rb index a4814885..c708322c 100644 --- a/spec/models/projection_spec.rb +++ b/spec/models/projection_spec.rb @@ -112,6 +112,18 @@ expect(http_client).to have_received(:get).with(%r{/full/max/0/default.jpg}) end end + + context "best fit size" do + let(:options) { { size: '!850,700', region: 'full' } } + + it 'returns original size when requested dimensions are larger' do + allow(HTTP).to receive(:use) + .and_return(http_client) + allow(http_client).to receive(:get).and_return(double(body: nil)) + subject.response + expect(http_client).to have_received(:get).with(%r{/full/!800,600/0/default.jpg}) + end + end end context 'for a restricted image' do