dragonfly-lossless_rotate 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4570113d02eed8571af6ccd48135730ecb435d85edc5db4f3c12dc5134fbb4c0
4
- data.tar.gz: 1c711083d0e1a89a0f13ade6e1d30488f4f565aaefda54fcde30c73b356e4b94
3
+ metadata.gz: 980d9f58a025a965308c14d93100cf22bf293803ae7d7df58ef8ae484c50690b
4
+ data.tar.gz: b7e6c1af2f809f227a84a5db967b5d0abfee1ae2f2098df9da626fd678fd216e
5
5
  SHA512:
6
- metadata.gz: 83923e26bc11d4cab7cbf1dfc30f1a81528917ff5454d5636eeb0d8a9920454639a6fa74c94820b84e804da5aa3ffd3ffa6c63c033284fd90ce839be8291743a
7
- data.tar.gz: 8dd6253e9ac9f9766439c87f26c285c0f8be8bfc1d7bba6ba92ca92b773cb5ab72d4b611f914425839d24ce62d4486643c477b9ad82a9262dab2edd275b3fc10
6
+ metadata.gz: b8ca9e89edd39b58071e79cc297b698bd60493a7a649e785e015dfe2d8de87b05da9e785fc8d69e29470f76ff28fa3f11328d63c57b158e29c20ea8c04d5546e
7
+ data.tar.gz: 4e3137e0458fcc1649df916dfd3459767e27859e85b743e721ebae6a8cc1e957b35b323f33eb3313f10c2a2acd822b01817e213b70358ce8d8c02673492d7ed4
@@ -0,0 +1,169 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+ # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
4
+ # to ignore them, so only the ones explicitly set in this file are enabled.
5
+ DisabledByDefault: true
6
+ Exclude:
7
+ - '**/templates/**/*'
8
+ - '**/vendor/**/*'
9
+ - 'actionpack/lib/action_dispatch/journey/parser.rb'
10
+ - 'railties/test/fixtures/tmp/**/*'
11
+
12
+ # Prefer &&/|| over and/or.
13
+ Style/AndOr:
14
+ Enabled: true
15
+
16
+ # Do not use braces for hash literals when they are the last argument of a
17
+ # method call.
18
+ Style/BracesAroundHashParameters:
19
+ Enabled: true
20
+ EnforcedStyle: context_dependent
21
+
22
+ # Align `when` with `case`.
23
+ Layout/CaseIndentation:
24
+ Enabled: true
25
+
26
+ # Align comments with method definitions.
27
+ Layout/CommentIndentation:
28
+ Enabled: true
29
+
30
+ Layout/ElseAlignment:
31
+ Enabled: true
32
+
33
+ # Align `end` with the matching keyword or starting expression except for
34
+ # assignments, where it should be aligned with the LHS.
35
+ Layout/EndAlignment:
36
+ Enabled: true
37
+ EnforcedStyleAlignWith: variable
38
+ AutoCorrect: true
39
+
40
+ Layout/EmptyLineAfterMagicComment:
41
+ Enabled: true
42
+
43
+ Layout/EmptyLinesAroundBlockBody:
44
+ Enabled: true
45
+
46
+ # In a regular class definition, no empty lines around the body.
47
+ Layout/EmptyLinesAroundClassBody:
48
+ Enabled: true
49
+
50
+ # In a regular method definition, no empty lines around the body.
51
+ Layout/EmptyLinesAroundMethodBody:
52
+ Enabled: true
53
+
54
+ # In a regular module definition, no empty lines around the body.
55
+ Layout/EmptyLinesAroundModuleBody:
56
+ Enabled: true
57
+
58
+ Layout/FirstParameterIndentation:
59
+ Enabled: true
60
+
61
+ # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
62
+ Style/HashSyntax:
63
+ Enabled: true
64
+
65
+ # Method definitions after `private` or `protected` isolated calls need one
66
+ # extra level of indentation.
67
+ Layout/IndentationConsistency:
68
+ Enabled: true
69
+ EnforcedStyle: rails
70
+
71
+ # Two spaces, no tabs (for indentation).
72
+ Layout/IndentationWidth:
73
+ Enabled: true
74
+
75
+ Layout/LeadingCommentSpace:
76
+ Enabled: true
77
+
78
+ Layout/SpaceAfterColon:
79
+ Enabled: true
80
+
81
+ Layout/SpaceAfterComma:
82
+ Enabled: true
83
+
84
+ Layout/SpaceAroundEqualsInParameterDefault:
85
+ Enabled: true
86
+
87
+ Layout/SpaceAroundKeyword:
88
+ Enabled: true
89
+
90
+ Layout/SpaceAroundOperators:
91
+ Enabled: true
92
+
93
+ Layout/SpaceBeforeComma:
94
+ Enabled: true
95
+
96
+ Layout/SpaceBeforeFirstArg:
97
+ Enabled: true
98
+
99
+ Style/DefWithParentheses:
100
+ Enabled: true
101
+
102
+ # Defining a method with parameters needs parentheses.
103
+ Style/MethodDefParentheses:
104
+ Enabled: true
105
+
106
+ Style/FrozenStringLiteralComment:
107
+ Enabled: true
108
+ EnforcedStyle: always
109
+ Exclude:
110
+ - 'actionview/test/**/*.builder'
111
+ - 'actionview/test/**/*.ruby'
112
+ - 'actionpack/test/**/*.builder'
113
+ - 'actionpack/test/**/*.ruby'
114
+ - 'activestorage/db/migrate/**/*.rb'
115
+
116
+ # Use `foo {}` not `foo{}`.
117
+ Layout/SpaceBeforeBlockBraces:
118
+ Enabled: true
119
+
120
+ # Use `foo { bar }` not `foo {bar}`.
121
+ Layout/SpaceInsideBlockBraces:
122
+ Enabled: true
123
+
124
+ # Use `{ a: 1 }` not `{a:1}`.
125
+ Layout/SpaceInsideHashLiteralBraces:
126
+ Enabled: true
127
+
128
+ Layout/SpaceInsideParens:
129
+ Enabled: true
130
+
131
+ # Check quotes usage according to lint rule below.
132
+ Style/StringLiterals:
133
+ Enabled: true
134
+ EnforcedStyle: double_quotes
135
+
136
+ # Detect hard tabs, no hard tabs.
137
+ Layout/Tab:
138
+ Enabled: true
139
+
140
+ # Blank lines should not have any spaces.
141
+ Layout/TrailingBlankLines:
142
+ Enabled: true
143
+
144
+ # No trailing whitespace.
145
+ Layout/TrailingWhitespace:
146
+ Enabled: true
147
+
148
+ # Use quotes for string literals when they are enough.
149
+ Style/UnneededPercentQ:
150
+ Enabled: true
151
+
152
+ # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
153
+ Lint/RequireParentheses:
154
+ Enabled: true
155
+
156
+ Lint/StringConversionInInterpolation:
157
+ Enabled: true
158
+
159
+ Style/RedundantReturn:
160
+ Enabled: true
161
+ AllowMultipleReturnValues: true
162
+
163
+ Style/Semicolon:
164
+ Enabled: true
165
+ AllowAsExpressionSeparator: true
166
+
167
+ # Prefer Foo.method over Foo::method
168
+ Style/ColonMethodCall:
169
+ Enabled: true
data/README.md CHANGED
@@ -49,9 +49,6 @@ JPEG only:
49
49
  @image.process(:lossless_rotate, 180)
50
50
  @image.process(:lossless_rotate, 270)
51
51
  @image.process(:lossless_rotate, -90)
52
-
53
- # Without JPEG optimization
54
- @image.process(:lossless_rotate, 90, optimize: false)
55
52
  ```
56
53
 
57
54
  With fallback for other formats (rotate via ImageMagick):
@@ -59,6 +56,19 @@ With fallback for other formats (rotate via ImageMagick):
59
56
  @image.process(:safe_lossless_rotate)
60
57
  ```
61
58
 
59
+ Other options:
60
+ ```ruby
61
+ # Without JPEG optimization (default: true)
62
+ @image.process(:lossless_rotate, 90, optimize: false)
63
+ # Set default value
64
+ plugin :lossless_rotate, libjpeg_optimize: false
65
+
66
+ # Create progressive JPEG file (default: false)
67
+ @image.process(:lossless_rotate, 90, progressive: true)
68
+ # Set default value
69
+ plugin :lossless_rotate, libjpeg_progressive: true
70
+ ```
71
+
62
72
  ## Benchmark
63
73
 
64
74
  - _libjpeg_ version 9b (17-Jan-2016)
@@ -1,23 +1,25 @@
1
- lib = File.expand_path("lib", __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "dragonfly/lossless_rotate/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "dragonfly-lossless_rotate"
7
- spec.version = Dragonfly::LosslessRotate::VERSION
8
- spec.summary = "Dragonfly lossless image rotate"
9
- spec.description = "Lossless rotating and compressing JPEG images via libjpeg tools"
10
- spec.author = "Maxim Perepelitsa"
11
- spec.email = "n0xff@outlook.com"
12
- spec.homepage = "https://github.com/n0xff/dragonfly-lossless_rotate"
13
- spec.license = "MIT"
14
-
15
- spec.requirements << "cjpeg"
16
- spec.requirements << "djpeg"
17
- spec.requirements << "jpegtran"
18
- spec.requirements << "pnmflip"
19
-
20
- spec.files = `git ls-files`.split($/)
21
-
22
- spec.add_runtime_dependency "dragonfly", "~> 1.0"
23
- end
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "dragonfly/lossless_rotate/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "dragonfly-lossless_rotate"
9
+ spec.version = Dragonfly::LosslessRotate::VERSION
10
+ spec.summary = "Dragonfly lossless image rotate"
11
+ spec.description = "Lossless rotating and compressing JPEG images via libjpeg tools"
12
+ spec.author = "Maxim Perepelitsa"
13
+ spec.email = "n0xff@outlook.com"
14
+ spec.homepage = "https://github.com/n0xff/dragonfly-lossless_rotate"
15
+ spec.license = "MIT"
16
+
17
+ spec.requirements << "cjpeg"
18
+ spec.requirements << "djpeg"
19
+ spec.requirements << "jpegtran"
20
+ spec.requirements << "pnmflip"
21
+
22
+ spec.files = `git ls-files`.split($/)
23
+
24
+ spec.add_runtime_dependency "dragonfly", "~> 1.0"
25
+ end
@@ -1,93 +1,102 @@
1
- require "dragonfly"
2
-
3
- Dragonfly::App.register_plugin(:lossless_rotate) { Dragonfly::LosslessRotate::Plugin.new }
4
-
5
- module Dragonfly
6
- class LosslessRotate
7
-
8
- class Plugin
9
- def call(app, opts={})
10
- app.env[:cjpeg_bin] = opts[:cjpeg_bin] || "cjpeg"
11
- app.env[:djpeg_bin] = opts[:djpeg_bin] || "djpeg"
12
- app.env[:jpegtran_bin] = opts[:jpegtran_bin] || "jpegtran"
13
- app.env[:pnmflip_bin] = opts[:pnmflip_bin] || "pnmflip"
14
-
15
- app.add_processor :lossless_rotate, Dragonfly::LosslessRotate::Rotate.new
16
- app.add_processor :safe_lossless_rotate, Dragonfly::LosslessRotate::SafeRotate.new
17
- end
18
- end
19
-
20
- # Only JPEG format
21
- class Rotate
22
- def call(content, degree=90, optimize: true)
23
- unless [90, 180, 270, -90, -180, -270].include?(degree)
24
- warn "Rotate by 90, 180 and 270 degrees allowed"
25
- degree = 90
26
- end
27
-
28
- rotate(content, degree, optimize)
29
- end
30
-
31
- private
32
-
33
- def rotate(content, degree, optimize)
34
- cjpeg_bin = content.env[:cjpeg_bin] || "cjpeg"
35
- djpeg_bin = content.env[:djpeg_bin] || "djpeg"
36
- jpegtran_bin = content.env[:jpegtran_bin] || "jpegtran"
37
- pnmflip_bin = content.env[:pnmflip_bin] || "pnmflip"
38
-
39
- content.shell_update escape: false do |old_path, new_path|
40
- optimize_option = " -optimize" if optimize
41
- output_command = if optimize
42
- " #{pnmflip_bin} -r#{pnmflip_degrees(degree)} | #{cjpeg_bin}#{optimize_option} > #{new_path}"
43
- else
44
- " convert - -rotate #{degree} JPG:#{new_path}"
45
- end
46
-
47
- lossless_rotate_command = "#{jpegtran_bin} -rotate #{jpegtran_degrees(degree)} -perfect#{optimize_option} #{old_path} > #{new_path}"
48
- lossy_rotate_command = "#{djpeg_bin} #{old_path} |#{output_command}"
49
-
50
- "#{lossless_rotate_command} || #{lossy_rotate_command}"
51
- end
52
- end
53
-
54
- def pnmflip_degrees(degree)
55
- {
56
- 90 => 270,
57
- 180 => 180,
58
- 270 => 90,
59
- -90 => 90,
60
- -180 => 180,
61
- -270 => 270
62
- }[degree]
63
- end
64
-
65
- def jpegtran_degrees(degree)
66
- {
67
- 90 => 90,
68
- 180 => 180,
69
- 270 => 180,
70
- -90 => 270,
71
- -180 => 180,
72
- -270 => 90
73
- }[degree]
74
- end
75
-
76
- def jpeg?(content)
77
- content.shell_eval { |path| "identify -format \%m #{path}" } == "JPEG"
78
- end
79
- end
80
-
81
- # All formats support by ImageMagick
82
- class SafeRotate < Rotate
83
- def rotate(content, degree, optimize)
84
- return super if jpeg?(content)
85
-
86
- content.shell_update escape: false do |old_path, new_path|
87
- "convert -rotate #{degree} #{old_path} > #{new_path}"
88
- end
89
- end
90
- private :rotate
91
- end
92
- end
93
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "dragonfly"
4
+
5
+ Dragonfly::App.register_plugin(:lossless_rotate) { Dragonfly::LosslessRotate::Plugin.new }
6
+
7
+ module Dragonfly
8
+ class LosslessRotate
9
+ class Plugin
10
+ def call(app, opts = {})
11
+ app.env[:cjpeg_bin] = opts[:cjpeg_bin] || "cjpeg"
12
+ app.env[:djpeg_bin] = opts[:djpeg_bin] || "djpeg"
13
+ app.env[:jpegtran_bin] = opts[:jpegtran_bin] || "jpegtran"
14
+ app.env[:pnmflip_bin] = opts[:pnmflip_bin] || "pnmflip"
15
+
16
+ app.env[:libjpeg_optimize] = opts[:libjpeg_optimize] || true
17
+ app.env[:libjpeg_progressive] = opts[:libjpeg_progressive] || false
18
+
19
+ app.add_processor :lossless_rotate, Dragonfly::LosslessRotate::Rotate.new
20
+ app.add_processor :safe_lossless_rotate, Dragonfly::LosslessRotate::SafeRotate.new
21
+ end
22
+ end
23
+
24
+ # Only JPEG format
25
+ class Rotate
26
+ def call(content, degree = 90, optimize: nil, progressive: nil)
27
+ unless [90, 180, 270, -90, -180, -270].include?(degree)
28
+ warn "Rotate only by 90, 180 and 270 degrees allowed"
29
+ degree = 90
30
+ end
31
+
32
+ optimize ||= content.env[:libjpeg_optimize]
33
+ progressive ||= content.env[:libjpeg_progressive]
34
+
35
+ rotate(content, degree, optimize, progressive)
36
+ end
37
+
38
+ private
39
+
40
+ def rotate(content, degree, optimize, progressive)
41
+ cjpeg_bin = content.env[:cjpeg_bin] || "cjpeg"
42
+ djpeg_bin = content.env[:djpeg_bin] || "djpeg"
43
+ jpegtran_bin = content.env[:jpegtran_bin] || "jpegtran"
44
+ pnmflip_bin = content.env[:pnmflip_bin] || "pnmflip"
45
+
46
+ content.shell_update escape: false do |old_path, new_path|
47
+ optimize_option = " -optimize" if optimize
48
+ progressive_option = " -progressive" if progressive
49
+
50
+ output_command = if optimize
51
+ " #{pnmflip_bin} -r#{pnmflip_degrees(degree)} | #{cjpeg_bin}#{progressive_option}#{optimize_option} > '#{new_path}'"
52
+ else
53
+ " convert - -rotate #{degree} 'JPG:#{new_path}'"
54
+ end
55
+
56
+ lossless_rotate_command = "#{jpegtran_bin} -rotate #{jpegtran_degrees(degree)} -perfect#{progressive_option}#{optimize_option} '#{old_path}' > '#{new_path}'"
57
+ lossy_rotate_command = "#{djpeg_bin} '#{old_path}' |#{output_command}"
58
+
59
+ "#{lossless_rotate_command} || #{lossy_rotate_command}"
60
+ end
61
+ end
62
+
63
+ def pnmflip_degrees(degree)
64
+ {
65
+ 90 => 270,
66
+ 180 => 180,
67
+ 270 => 90,
68
+ -90 => 90,
69
+ -180 => 180,
70
+ -270 => 270
71
+ }[degree]
72
+ end
73
+
74
+ def jpegtran_degrees(degree)
75
+ {
76
+ 90 => 90,
77
+ 180 => 180,
78
+ 270 => 180,
79
+ -90 => 270,
80
+ -180 => 180,
81
+ -270 => 90
82
+ }[degree]
83
+ end
84
+
85
+ def jpeg?(content)
86
+ content.shell_eval { |path| "identify -format \%m #{path}" } == "JPEG"
87
+ end
88
+ end
89
+
90
+ # All formats support by ImageMagick
91
+ class SafeRotate < Rotate
92
+ def rotate(content, degree, optimize, progressive)
93
+ return super if jpeg?(content)
94
+
95
+ content.shell_update do |old_path, new_path|
96
+ "convert #{old_path} -rotate #{degree} #{new_path}"
97
+ end
98
+ end
99
+ private :rotate
100
+ end
101
+ end
102
+ end
@@ -1,5 +1,7 @@
1
- module Dragonfly
2
- class LosslessRotate
3
- VERSION = "0.1.0"
4
- end
5
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Dragonfly
4
+ class LosslessRotate
5
+ VERSION = "0.1.1"
6
+ end
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dragonfly-lossless_rotate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxim Perepelitsa
@@ -30,6 +30,7 @@ executables: []
30
30
  extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
+ - ".rubocop.yml"
33
34
  - README.md
34
35
  - dragonfly-lossless_rotate.gemspec
35
36
  - lib/dragonfly/lossless_rotate.rb