riiif 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0af476f4ae806dfd50b80d55822b1b4e737bca3
4
- data.tar.gz: a19cc06b6257e2e8bfc20e10ebca47d842b71521
3
+ metadata.gz: 9ad33e2e0d258079efa25eef4e206dd4099996dd
4
+ data.tar.gz: 960a01a9a73dcf961ce4c945f6a2fcd64adca6ad
5
5
  SHA512:
6
- metadata.gz: bcfa15704d359abae49010c15e118f24a4107c56d0f5839a5cb8494216dabf7e6b8207338988b13f54b4ed39d37fa8857e6426a5974d376011d5bcdc1a1036f9
7
- data.tar.gz: 521ca263dd137a5a96e9d816f84576f04b3e175e0fc7c9382fdc33a88be375ff39a23b288645054f3c64142c9921fbd4c188ad8f0d57bccbf97ab7003ac96a60
6
+ metadata.gz: 4d6ead011f1e16fd7559fd67df911a1e964a4a8f17c73a549e4f9473b511021b675bbbe6b731cb86528a899138445a27427aab42e1a264ffb8e5b7d1869ba10d
7
+ data.tar.gz: 58eea4d035b7ac49adb4fa8fc91537e76114ee76d025fde5538502e0bfb9c5e672cae5b109a9a63ad0ddbd853652820b9612b7ac2297c7055eb40ac29865cd47
data/.rubocop.yml CHANGED
@@ -1,4 +1,12 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
+ AllCops:
4
+ TargetRubyVersion: 2.1
5
+ DisplayCopNames: true
6
+
3
7
  Style/IndentationConsistency:
4
8
  EnforcedStyle: rails
9
+
10
+ Metrics/BlockLength:
11
+ Exclude:
12
+ - spec/**/*
data/.rubocop_todo.yml CHANGED
@@ -28,11 +28,6 @@ Lint/UselessAssignment:
28
28
  Metrics/AbcSize:
29
29
  Max: 38
30
30
 
31
- # Offense count: 12
32
- # Configuration parameters: CountComments, ExcludedMethods.
33
- Metrics/BlockLength:
34
- Max: 143
35
-
36
31
  # Offense count: 1
37
32
  # Configuration parameters: CountComments.
38
33
  Metrics/ClassLength:
@@ -46,17 +41,13 @@ Metrics/CyclomaticComplexity:
46
41
  # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
47
42
  # URISchemes: http, https
48
43
  Metrics/LineLength:
49
- Max: 160
44
+ Max: 120
50
45
 
51
46
  # Offense count: 7
52
47
  # Configuration parameters: CountComments.
53
48
  Metrics/MethodLength:
54
49
  Max: 21
55
50
 
56
- # Offense count: 2
57
- Metrics/PerceivedComplexity:
58
- Max: 9
59
-
60
51
  # Offense count: 1
61
52
  # Cop supports --auto-correct.
62
53
  Performance/RedundantMatch:
@@ -59,7 +59,9 @@ module Riiif
59
59
  ##
60
60
  # @return [ActiveSupport::HashWithIndifferentAccess]
61
61
  def image_request_params
62
- params.permit(:region, :size, :rotation, :quality, :format).to_h
62
+ result = params.permit(:region, :size, :rotation, :quality, :format).to_h
63
+ return result.with_indifferent_access if Rails.version < '5'
64
+ result
63
65
  end
64
66
 
65
67
  def authorization_service
@@ -1,12 +1,9 @@
1
- require 'open3'
2
1
  module Riiif
3
2
  class File
4
- include Open3
5
- include ActiveSupport::Benchmarkable
6
-
7
3
  attr_reader :path
8
4
 
9
- delegate :logger, to: :Rails
5
+ class_attribute :info_extractor_class
6
+ self.info_extractor_class = ImageMagickInfoExtractor
10
7
 
11
8
  # @param input_path [String] The location of an image file
12
9
  def initialize(input_path, tempfile = nil)
@@ -34,48 +31,31 @@ module Riiif
34
31
 
35
32
  end
36
33
 
37
- def extract(options)
38
-
34
+ # @param [Transformation] transformation
35
+ def extract(transformation)
39
36
  command = 'convert'
40
- command << " -crop #{options[:crop]}" if options[:crop]
41
- command << " -resize #{options[:size]}" if options[:size]
42
- if options[:rotation]
43
- command << " -virtual-pixel white +distort srt #{options[:rotation]}"
37
+ command << " -crop #{transformation.crop}" if transformation.crop
38
+ command << " -resize #{transformation.size}" if transformation.size
39
+ if transformation.rotation
40
+ command << " -virtual-pixel white +distort srt #{transformation.rotation}"
44
41
  end
45
42
 
46
- case options[:quality]
43
+ case transformation.quality
47
44
  when 'grey'
48
45
  command << ' -colorspace Gray'
49
46
  when 'bitonal'
50
47
  command << ' -colorspace Gray'
51
48
  command << ' -type Bilevel'
52
49
  end
53
- command << " #{path} #{options[:format]}:-"
50
+ command << " #{path} #{transformation.format}:-"
54
51
  execute(command)
55
52
  end
56
53
 
57
54
  def info
58
- return @info if @info
59
- height, width = execute("identify -format %hx%w #{path}").split('x')
60
- @info = { height: Integer(height), width: Integer(width) }
55
+ @info ||= info_extractor_class.new(path).extract
61
56
  end
62
57
 
63
- private
64
-
65
- def execute(command)
66
- out = nil
67
- benchmark("Riiif executed #{command}") do
68
- stdin, stdout, stderr, wait_thr = popen3(command)
69
- stdin.close
70
- stdout.binmode
71
- out = stdout.read
72
- stdout.close
73
- err = stderr.read
74
- stderr.close
75
- raise "Unable to execute command \"#{command}\"\n#{err}" unless wait_thr.value.success?
76
- end
77
- out
78
- end
79
-
58
+ delegate :execute, to: Riiif::CommandRunner
59
+ private :execute
80
60
  end
81
61
  end
@@ -42,7 +42,10 @@ module Riiif
42
42
  end
43
43
 
44
44
  def info
45
- info_service.call(id, image)
45
+ @info ||= begin
46
+ result = info_service.call(id, image)
47
+ ImageInformation.new(result[:width], result[:height])
48
+ end
46
49
  end
47
50
 
48
51
  class << self
@@ -52,7 +55,7 @@ module Riiif
52
55
 
53
56
 
54
57
  def cache_key(id, options)
55
- str = options.merge(id: id).delete_if { |_, v| v.nil? }.to_s
58
+ str = options.to_h.merge(id: id).delete_if { |_, v| v.nil? }.to_s
56
59
  # Use a MD5 digest to ensure the keys aren't too long.
57
60
  Digest::MD5.hexdigest(str)
58
61
  end
@@ -62,14 +65,15 @@ module Riiif
62
65
 
63
66
  ##
64
67
  # @param [ActiveSupport::HashWithIndifferentAccess] options
68
+ # @return [Transformation]
65
69
  def decode_options!(options)
66
70
  raise ArgumentError, "You must provide a format. You provided #{options}" unless options[:format]
67
- options[:crop] = decode_region(options.delete(:region))
68
- options[:size] = decode_size(options.delete(:size))
69
- options[:quality] = decode_quality(options[:quality])
70
- options[:rotation] = decode_rotation(options[:rotation])
71
71
  validate_format!(options[:format])
72
- options
72
+ Riiif::Transformation.new(decode_region(options.delete(:region)),
73
+ decode_size(options.delete(:size)),
74
+ decode_quality(options[:quality]),
75
+ decode_rotation(options[:rotation]),
76
+ options[:format])
73
77
  end
74
78
 
75
79
  def decode_quality(quality)
@@ -94,47 +98,37 @@ module Riiif
94
98
 
95
99
  def decode_region(region)
96
100
  if region.nil? || region == 'full'
97
- nil
101
+ Riiif::Region::Imagemagick::FullDecoder.new.decode
98
102
  elsif md = /^pct:(\d+),(\d+),(\d+),(\d+)$/.match(region)
99
- # Image magic can't do percentage offsets, so we have to calculate it
100
- offset_x = (info[:width] * Integer(md[1]).to_f / 100).round
101
- offset_y = (info[:height] * Integer(md[2]).to_f / 100).round
102
- "#{md[3]}%x#{md[4]}+#{offset_x}+#{offset_y}"
103
+ Riiif::Region::Imagemagick::PercentageDecoder
104
+ .new(info, md[1], md[2], md[3], md[4]).decode
103
105
  elsif md = /^(\d+),(\d+),(\d+),(\d+)$/.match(region)
104
- "#{md[3]}x#{md[4]}+#{md[1]}+#{md[2]}"
106
+ Riiif::Region::Imagemagick::AbsoluteDecoder.new(md[1], md[2], md[3], md[4]).decode
105
107
  elsif region == 'square'
106
- w = info[:width]
107
- h = info[:height]
108
- min, max = [w, h].minmax
109
-
110
- offset = (max - min) / 2
111
- if h >= w
112
- "#{min}x#{min}+0+#{offset}"
113
- else
114
- "#{min}x#{min}+#{offset}+0"
115
- end
108
+ Riiif::Region::Imagemagick::SquareDecoder.new(info).decode
116
109
  else
117
110
  raise InvalidAttributeError, "Invalid region: #{region}"
118
111
  end
119
112
  end
120
113
 
114
+ # rubocop:disable Metrics/PerceivedComplexity
121
115
  def decode_size(size)
122
116
  if size.nil? || size == 'full'
123
- nil
117
+ Riiif::Size::Imagemagick::FullDecoder.new.decode
124
118
  elsif md = /^,(\d+)$/.match(size)
125
- "x#{md[1]}"
119
+ Riiif::Size::Imagemagick::HeightDecoder.new(md[1]).decode
126
120
  elsif md = /^(\d+),$/.match(size)
127
- (md[1]).to_s
121
+ Riiif::Size::Imagemagick::WidthDecoder.new(md[1]).decode
128
122
  elsif md = /^pct:(\d+(.\d+)?)$/.match(size)
129
- "#{md[1]}%"
123
+ Riiif::Size::Imagemagick::PercentDecoder.new(md[1]).decode
130
124
  elsif md = /^(\d+),(\d+)$/.match(size)
131
- "#{md[1]}x#{md[2]}!"
125
+ Riiif::Size::Imagemagick::AbsoluteDecoder.new(md[1], md[2]).decode
132
126
  elsif md = /^!(\d+),(\d+)$/.match(size)
133
- "#{md[1]}x#{md[2]}"
127
+ Riiif::Size::Imagemagick::BestFitDecoder.new(md[1], md[2]).decode
134
128
  else
135
129
  raise InvalidAttributeError, "Invalid size: #{size}"
136
130
  end
137
131
  end
138
-
132
+ # rubocop:enable Metrics/PerceivedComplexity
139
133
  end
140
134
  end
@@ -0,0 +1,28 @@
1
+ require 'open3'
2
+ module Riiif
3
+ # Runs shell commands under benchmark and saves the output
4
+ class CommandRunner
5
+ include Open3
6
+ include ActiveSupport::Benchmarkable
7
+ delegate :logger, to: :Rails
8
+
9
+ def execute(command)
10
+ out = nil
11
+ benchmark("Riiif executed #{command}") do
12
+ stdin, stdout, stderr, wait_thr = popen3(command)
13
+ stdin.close
14
+ stdout.binmode
15
+ out = stdout.read
16
+ stdout.close
17
+ err = stderr.read
18
+ stderr.close
19
+ raise "Unable to execute command \"#{command}\"\n#{err}" unless wait_thr.value.success?
20
+ end
21
+ out
22
+ end
23
+
24
+ def self.execute(command)
25
+ new.execute(command)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module Riiif
2
+ # Get height and width information using imagemagick to interrogate the file
3
+ class ImageMagickInfoExtractor
4
+ def initialize(path)
5
+ @path = path
6
+ end
7
+
8
+ def extract
9
+ height, width = Riiif::CommandRunner.execute("identify -format %hx%w #{@path}").split('x')
10
+ { height: Integer(height), width: Integer(width) }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ module Riiif
2
+ module Region
3
+ module Imagemagick
4
+ # decodes requested cooridnates into an imagemagick crop directive
5
+ class AbsoluteDecoder
6
+ def initialize(x, y, width, height)
7
+ @x = x
8
+ @y = y
9
+ @width = width
10
+ @height = height
11
+ end
12
+
13
+ # @return [String] a region for imagemagick to decode
14
+ # (appropriate for passing to the -crop parameter)
15
+ def decode
16
+ "#{@width}x#{@height}+#{@x}+#{@y}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ module Riiif
2
+ module Region
3
+ module Imagemagick
4
+ # The image or region is not scaled, and is returned at its full size.
5
+ class FullDecoder
6
+ # @return [NilClass] a region for imagemagick to decode
7
+ # the nil implies no cropping needed
8
+ def decode
9
+ nil
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ module Riiif
2
+ module Region
3
+ module Imagemagick
4
+ # decodes requested cooridnates into an imagemagick crop directive
5
+ class PercentageDecoder
6
+ def initialize(image_info, x, y, width, height)
7
+ @image_info = image_info
8
+ @x = x
9
+ @y = y
10
+ @width = width
11
+ @height = height
12
+ end
13
+
14
+ # Imagemagick can't do percentage offsets, so we have to calculate it
15
+ # @return [String] a region for imagemagick to decode
16
+ # (appropriate for passing to the -crop parameter)
17
+ def decode
18
+ "#{@width}%x#{@height}+#{offset_x}+#{offset_y}"
19
+ end
20
+
21
+ private
22
+
23
+ def offset_x
24
+ (@image_info.width * Integer(@x).to_f / 100).round
25
+ end
26
+
27
+ def offset_y
28
+ (@image_info.height * Integer(@y).to_f / 100).round
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ module Riiif
2
+ module Region
3
+ module Imagemagick
4
+ # decodes requested cooridnates into an imagemagick crop directive
5
+ class SquareDecoder
6
+ def initialize(image_info)
7
+ @image_info = image_info
8
+ end
9
+
10
+ # @return [String] a square region for imagemagick to decode
11
+ # (appropriate for passing to the -crop parameter)
12
+ def decode
13
+ min, max = [@image_info.width, @image_info.height].minmax
14
+
15
+ offset = (max - min) / 2
16
+ if @image_info.height >= @image_info.width
17
+ "#{min}x#{min}+0+#{offset}"
18
+ else
19
+ "#{min}x#{min}+#{offset}+0"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ module Riiif
2
+ module Size
3
+ module Imagemagick
4
+ # The width and height of the returned image are exactly w and h.
5
+ # The aspect ratio of the returned image may be different than the extracted
6
+ # region, resulting in a distorted image.
7
+ class AbsoluteDecoder
8
+ def initialize(width, height)
9
+ @width = width
10
+ @height = height
11
+ end
12
+
13
+ # @return [String] a resize directive for imagemagick to use
14
+ def decode
15
+ "#{@width}x#{@height}!"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module Riiif
2
+ module Size
3
+ module Imagemagick
4
+ # The image content is scaled for the best fit such that the resulting width and
5
+ # height are less than or equal to the requested width and height.
6
+ class BestFitDecoder
7
+ def initialize(width, height)
8
+ @width = width
9
+ @height = height
10
+ end
11
+
12
+ # @return [String] a resize directive for imagemagick to use
13
+ def decode
14
+ "#{@width}x#{@height}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ module Riiif
2
+ module Size
3
+ module Imagemagick
4
+ # decodes requested size into an imagemagick resize directive
5
+ class FullDecoder
6
+ # @return [NilClass] a size for imagemagick to decode
7
+ # the nil implies no resizing needed
8
+ def decode
9
+ nil
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module Riiif
2
+ module Size
3
+ module Imagemagick
4
+ # The image or region should be scaled so that its height is exactly equal
5
+ # to the provided parameter, and the width will be a calculated value that
6
+ # maintains the aspect ratio of the extracted region
7
+ class HeightDecoder
8
+ def initialize(height)
9
+ @height = height
10
+ end
11
+
12
+ # @return [String] a resize directive for imagemagick to use
13
+ def decode
14
+ "x#{@height}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Riiif
2
+ module Size
3
+ module Imagemagick
4
+ # The width and height of the returned image is scaled to n% of the width and height
5
+ # of the extracted region. The aspect ratio of the returned image is the same as that
6
+ # of the extracted region.
7
+ class PercentDecoder
8
+ def initialize(n)
9
+ @n = n
10
+ end
11
+
12
+ # @return [String] a resize directive for imagemagick to use
13
+ def decode
14
+ "#{@n}%"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Riiif
2
+ module Size
3
+ module Imagemagick
4
+ # The image or region should be scaled so that its width is exactly equal
5
+ # to the provided parameter, and the height will be a calculated value that
6
+ # maintains the aspect ratio of the extracted region
7
+ class WidthDecoder
8
+ def initialize(width)
9
+ @width = width
10
+ end
11
+
12
+ # @return [String] a resize directive for imagemagick to use
13
+ def decode
14
+ @width.to_s
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/riiif/routes.rb CHANGED
@@ -22,7 +22,9 @@ module Riiif
22
22
  defaults: { format: 'jpg', rotation: '0', region: 'full', quality: 'default', model: resource },
23
23
  as: options[:as] || 'image'
24
24
 
25
- get "#{route_prefix}/:id/info.json" => 'riiif/images#info', defaults: { format: 'json', model: resource }, as: [options[:as], 'info'].compact.join('_')
25
+ get "#{route_prefix}/:id/info.json" => 'riiif/images#info',
26
+ defaults: { format: 'json', model: resource },
27
+ as: [options[:as], 'info'].compact.join('_')
26
28
 
27
29
  # This doesn't work presently
28
30
  # get "#{route_prefix}/:id", to: redirect("#{route_prefix}/%{id}/info.json")
data/lib/riiif/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Riiif
2
- VERSION = '1.1.1'.freeze
2
+ VERSION = '1.1.2'.freeze
3
3
  end
data/lib/riiif.rb CHANGED
@@ -20,5 +20,7 @@ module Riiif
20
20
  end
21
21
  end
22
22
 
23
+ Transformation = Struct.new(:crop, :size, :quality, :rotation, :format)
24
+ ImageInformation = Struct.new(:width, :height)
23
25
  mattr_accessor :not_found_image # the image to use when a lookup fails
24
26
  end
data/riiif.gemspec CHANGED
@@ -24,6 +24,6 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency 'engine_cart', '~> 0.8'
25
25
  spec.add_development_dependency 'rspec-rails'
26
26
  spec.add_development_dependency 'sqlite3'
27
- spec.add_development_dependency 'rubocop', '~> 0.41.2'
28
- spec.add_development_dependency 'rubocop-rspec', '~> 1.5'
27
+ spec.add_development_dependency 'rubocop', '~> 0.47.1'
28
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.13'
29
29
  end
@@ -7,6 +7,7 @@ describe Riiif::AkubraSystemFileResolver do
7
7
  end
8
8
 
9
9
  it 'gets the jpeg2000 file' do
10
- expect(subject.find('demo:1').path).to eq Riiif::File.new(Dir.glob(subject.pathroot + '22/7e/9/info%3Afedora%2Fdemo%3A1%2Fjp2%2Fjp2.0').first).path
10
+ file = Dir.glob(subject.pathroot + '22/7e/9/info%3Afedora%2Fdemo%3A1%2Fjp2%2Fjp2.0').first
11
+ expect(subject.find('demo:1').path).to eq Riiif::File.new(file).path
11
12
  end
12
13
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Riiif::Image do
3
+ RSpec.describe Riiif::Image do
4
4
  before { Rails.cache.clear }
5
5
  let(:filename) { File.expand_path('spec/samples/world.jp2') }
6
6
  subject { described_class.new('world') }
@@ -16,7 +16,7 @@ describe Riiif::Image do
16
16
  it 'is able to override the file used for the Image' do
17
17
  img = described_class.new('some_id', Riiif::File.new(filename))
18
18
  expect(img.id).to eq 'some_id'
19
- expect(img.info).to eq height: 400, width: 800
19
+ expect(img.info).to eq Riiif::ImageInformation.new(800, 400)
20
20
  end
21
21
 
22
22
  describe 'without a format' do
@@ -27,7 +27,7 @@ describe Riiif::Image do
27
27
 
28
28
  describe 'info' do
29
29
  it 'returns the data' do
30
- expect(subject.info).to eq height: 400, width: 800
30
+ expect(subject.info).to eq Riiif::ImageInformation.new(800, 400)
31
31
  end
32
32
  end
33
33
 
@@ -45,7 +45,7 @@ describe Riiif::Image do
45
45
  describe 'get info' do
46
46
  subject { described_class.new('Cave_26,_Ajanta') }
47
47
  it 'is easy' do
48
- expect(subject.info).to eq height: 390, width: 600
48
+ expect(subject.info).to eq Riiif::ImageInformation.new(600, 390)
49
49
  end
50
50
  end
51
51
 
@@ -63,21 +63,25 @@ describe Riiif::Image do
63
63
  describe 'mogrify' do
64
64
  describe 'region' do
65
65
  it 'returns the original when specifing full size' do
66
- expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
66
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
67
67
  subject.render(region: 'full', format: 'png')
68
68
  end
69
69
  it 'handles absolute geometry' do
70
- expect(subject.image).to receive(:execute).with("convert -crop 60x75+80+15 #{filename} png:-")
70
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -crop 60x75+80+15 #{filename} png:-")
71
71
  subject.render(region: '80,15,60,75', format: 'png')
72
72
  end
73
+
73
74
  it 'handles percent geometry' do
74
- expect(subject.image).to receive(:execute).with("identify -format %hx%w #{filename}").and_return('131x175')
75
- expect(subject.image).to receive(:execute).with("convert -crop 80%x70+18+13 #{filename} png:-")
75
+ expect(Riiif::CommandRunner).to receive(:execute)
76
+ .with("identify -format %hx%w #{filename}").and_return('131x175')
77
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -crop 80%x70+18+13 #{filename} png:-")
76
78
  subject.render(region: 'pct:10,10,80,70', format: 'png')
77
79
  end
80
+
78
81
  it 'handles square geometry' do
79
- expect(subject.image).to receive(:execute).with("identify -format %hx%w #{filename}").and_return('131x175')
80
- expect(subject.image).to receive(:execute).with("convert -crop 131x131+22+0 #{filename} png:-")
82
+ expect(Riiif::CommandRunner).to receive(:execute)
83
+ .with("identify -format %hx%w #{filename}").and_return('131x175')
84
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -crop 131x131+22+0 #{filename} png:-")
81
85
  subject.render(region: 'square', format: 'png')
82
86
  end
83
87
  it 'raises an error for invalid geometry' do
@@ -87,31 +91,31 @@ describe Riiif::Image do
87
91
 
88
92
  describe 'resize' do
89
93
  it 'returns the original when specifing full size' do
90
- expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
94
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
91
95
  subject.render(size: 'full', format: 'png')
92
96
  end
93
97
  it 'handles integer percent sizes' do
94
- expect(subject.image).to receive(:execute).with("convert -resize 50% #{filename} png:-")
98
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 50% #{filename} png:-")
95
99
  subject.render(size: 'pct:50', format: 'png')
96
100
  end
97
101
  it 'handles float percent sizes' do
98
- expect(subject.image).to receive(:execute).with("convert -resize 12.5% #{filename} png:-")
102
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 12.5% #{filename} png:-")
99
103
  subject.render(size: 'pct:12.5', format: 'png')
100
104
  end
101
105
  it 'handles w,' do
102
- expect(subject.image).to receive(:execute).with("convert -resize 50 #{filename} png:-")
106
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 50 #{filename} png:-")
103
107
  subject.render(size: '50,', format: 'png')
104
108
  end
105
109
  it 'handles ,h' do
106
- expect(subject.image).to receive(:execute).with("convert -resize x50 #{filename} png:-")
110
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize x50 #{filename} png:-")
107
111
  subject.render(size: ',50', format: 'png')
108
112
  end
109
113
  it 'handles w,h' do
110
- expect(subject.image).to receive(:execute).with("convert -resize 150x75! #{filename} png:-")
114
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 150x75! #{filename} png:-")
111
115
  subject.render(size: '150,75', format: 'png')
112
116
  end
113
117
  it 'handles bestfit (!w,h)' do
114
- expect(subject.image).to receive(:execute).with("convert -resize 150x75 #{filename} png:-")
118
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 150x75 #{filename} png:-")
115
119
  subject.render(size: '!150,75', format: 'png')
116
120
  end
117
121
  it 'raises an error for invalid size' do
@@ -121,11 +125,12 @@ describe Riiif::Image do
121
125
 
122
126
  describe 'rotate' do
123
127
  it 'returns the original when specifing full size' do
124
- expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
128
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
125
129
  subject.render(rotation: '0', format: 'png')
126
130
  end
127
131
  it 'handles floats' do
128
- expect(subject.image).to receive(:execute).with("convert -virtual-pixel white +distort srt 22.5 #{filename} png:-")
132
+ expect(Riiif::CommandRunner).to receive(:execute)
133
+ .with("convert -virtual-pixel white +distort srt 22.5 #{filename} png:-")
129
134
  subject.render(rotation: '22.5', format: 'png')
130
135
  end
131
136
  it 'raises an error for invalid angle' do
@@ -135,19 +140,20 @@ describe Riiif::Image do
135
140
 
136
141
  describe 'quality' do
137
142
  it 'returns the original when specifing default' do
138
- expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
143
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
139
144
  subject.render(quality: 'default', format: 'png')
140
145
  end
141
146
  it 'returns the original when specifing color' do
142
- expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
147
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
143
148
  subject.render(quality: 'color', format: 'png')
144
149
  end
145
150
  it 'converts to grayscale' do
146
- expect(subject.image).to receive(:execute).with("convert -colorspace Gray #{filename} png:-")
151
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -colorspace Gray #{filename} png:-")
147
152
  subject.render(quality: 'grey', format: 'png')
148
153
  end
149
154
  it 'converts to bitonal' do
150
- expect(subject.image).to receive(:execute).with("convert -colorspace Gray -type Bilevel #{filename} png:-")
155
+ expect(Riiif::CommandRunner).to receive(:execute)
156
+ .with("convert -colorspace Gray -type Bilevel #{filename} png:-")
151
157
  subject.render(quality: 'bitonal', format: 'png')
152
158
  end
153
159
  it 'raises an error for invalid angle' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riiif
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-09 00:00:00.000000000 Z
11
+ date: 2017-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -106,28 +106,28 @@ dependencies:
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: 0.41.2
109
+ version: 0.47.1
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: 0.41.2
116
+ version: 0.47.1
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: rubocop-rspec
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: '1.5'
123
+ version: '1.13'
124
124
  type: :development
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '1.5'
130
+ version: '1.13'
131
131
  description: A IIIF image server
132
132
  email:
133
133
  - justin@curationexperts.com
@@ -148,6 +148,18 @@ files:
148
148
  - app/controllers/riiif/images_controller.rb
149
149
  - app/models/riiif/file.rb
150
150
  - app/models/riiif/image.rb
151
+ - app/services/riiif/command_runner.rb
152
+ - app/services/riiif/image_magick_info_extractor.rb
153
+ - app/services/riiif/region/imagemagick/absolute_decoder.rb
154
+ - app/services/riiif/region/imagemagick/full_decoder.rb
155
+ - app/services/riiif/region/imagemagick/percentage_decoder.rb
156
+ - app/services/riiif/region/imagemagick/square_decoder.rb
157
+ - app/services/riiif/size/imagemagick/absolute_decoder.rb
158
+ - app/services/riiif/size/imagemagick/best_fit_decoder.rb
159
+ - app/services/riiif/size/imagemagick/full_decoder.rb
160
+ - app/services/riiif/size/imagemagick/height_decoder.rb
161
+ - app/services/riiif/size/imagemagick/percent_decoder.rb
162
+ - app/services/riiif/size/imagemagick/width_decoder.rb
151
163
  - config/routes.rb
152
164
  - lib/riiif.rb
153
165
  - lib/riiif/abstract_file_system_resolver.rb
@@ -190,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
202
  version: '0'
191
203
  requirements: []
192
204
  rubyforge_project:
193
- rubygems_version: 2.6.10
205
+ rubygems_version: 2.6.8
194
206
  signing_key:
195
207
  specification_version: 4
196
208
  summary: A rails engine that support IIIF requests