dhash-vips 0.1.0.3 → 0.1.1.0

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: 2b90b4abcd617f0e285dd3399338b4114d921624
4
- data.tar.gz: d47a8e51a8e7a2bf28b60d0259dc350f8b5e4fa0
3
+ metadata.gz: e462c5c41c5f2c5916223c083f22d16ae37a062b
4
+ data.tar.gz: 3261d15852334f30b59bd53cbfdd03e4a6db8758
5
5
  SHA512:
6
- metadata.gz: 3b8b2ce65f3bdfd90d03e3a069e30c61be4a9bf1fc40f9d4beace8216165383d7f54572e996e101ab9fd6f056b260676a9ed465b8860bd1a6e17a4228b859909
7
- data.tar.gz: 2ea40198fa4c6ed05183d610b2ca558a6ad67a386e69c127dbc0afac5723686025bd4644cc7297c300d9173b212788cc1ab4f242ad849ed7ee50dbc462dd5f08
6
+ metadata.gz: 80c90dd232d5c9ea5ccfd65d715c48bafb56ca94aac70e45ced117ad27e748ae81030010f4eb62f963b86f0854d1a9c6d3f4174de730cb8f763fd7dcfcf60f89
7
+ data.tar.gz: bbe1bee6c35949f68fe886512668d3ea5215daa2207f49fe3f2db51b5ea3c1829d2fb7c69a4d3b05a05afab6df7d243ba37d10d6de39aae1088b404189d43326
data/README.md CHANGED
@@ -93,10 +93,6 @@ end
93
93
 
94
94
  * The above `15` and `25` constants are found empirically and just work enough well for 8-byte hashes. To find these thresholds we can run a rake task with hardcoded test cases (pairs of photos from the same photosession are not the same but are considered to be enough 'similar' for the purpose of this benchmark):
95
95
 
96
- $ vips -v
97
- vips-8.9.2-Tue Apr 21 09:26:11 UTC 2020
98
- $ identify -version | head -1
99
- Version: ImageMagick 6.9.11-24 Q16 x86_64 2020-07-18 https://imagemagick.org
100
96
  $ rake compare_quality
101
97
 
102
98
  Dhash Phamilie DHashVips::DHash DHashVips::IDHash DHashVips::IDHash(4)
@@ -111,45 +107,9 @@ end
111
107
 
112
108
  * Methods were renamed from `#calculate` to `#fingerprint` and from `#hamming` to `#distance`.
113
109
  * The `DHash#calculate` accepts `hash_size` optional parameter that is 8 by default. The `IDHash#fingerprint`'s optional parameter is called `power` and works in a bit different way: 3 means 8 and 4 means 16 -- other sizes are not supported because they don't seem to be useful (higher fingerprint resolution makes it vulnerable to image shifts and croppings, also `#distance` becomes much slower). Because IDHash's fingerprint is more complex than DHash's one it's not that straight forward to compare them so under the hood the `#distance` method have to check the size of fingerprint. If you are sure that fingerprints were made with power=3 then to skip the check you may use the `#distance3` method directly.
114
- * The `#distance3` method will use Ruby C extension that is around 15 times faster than pure Ruby implementation -- native extension is currently hardcoded to be compiled only if it's macOS and rbenv Ruby 2.3.8 installed with `-k` flag but if you know how to make the gem gracefully fallback to native Ruby if `make` fails let me know or make a pull request. So the full benchmark:
110
+ * The `#distance3` method will try to compile and use the Ruby C extension that is around 15 times faster than pure Ruby implementation -- native extension currently works on macOS rbenv Ruby from 2.3.8 to 2.4.9 installed with rbenv `-k` flag. So the full benchmark:
115
111
 
116
- * Ruby 2.0.0
117
-
118
- $ bundle exec rake compare_speed
119
-
120
- load the image and calculate the fingerprint:
121
- user system total real
122
- Dhash 12.400000 0.820000 13.220000 ( 13.329952)
123
- DHashVips::DHash 1.330000 0.230000 1.560000 ( 1.509826)
124
- DHashVips::IDHash 1.060000 0.090000 1.150000 ( 1.100332)
125
- DHashVips::IDHash 4 1.030000 0.080000 1.110000 ( 1.089148)
126
-
127
- measure the distance (32*32*1000 times):
128
- user system total real
129
- Dhash hamming 3.140000 0.020000 3.160000 ( 3.179392)
130
- DHashVips::DHash hamming 3.040000 0.020000 3.060000 ( 3.095190)
131
- DHashVips::IDHash distance 8.170000 0.040000 8.210000 ( 8.279950)
132
- DHashVips::IDHash distance3 6.720000 0.030000 6.750000 ( 6.790900)
133
- DHashVips::IDHash distance 4 24.430000 0.130000 24.560000 ( 24.652625)
134
-
135
- * Ruby 2.3.3 seems to have some bit arithmetics improvement compared to 2.0:
136
-
137
- load the image and calculate the fingerprint:
138
- user system total real
139
- Dhash 13.110000 0.950000 14.060000 ( 14.537057)
140
- DHashVips::DHash 1.480000 0.310000 1.790000 ( 1.808787)
141
- DHashVips::IDHash 1.080000 0.100000 1.180000 ( 1.156446)
142
- DHashVips::IDHash 4 1.030000 0.090000 1.120000 ( 1.076117)
143
-
144
- measure the distance (32*32*1000 times):
145
- user system total real
146
- Dhash hamming 1.770000 0.010000 1.780000 ( 1.815612)
147
- DHashVips::DHash hamming 1.810000 0.010000 1.820000 ( 1.875666)
148
- DHashVips::IDHash distance 4.250000 0.020000 4.270000 ( 4.350071)
149
- DHashVips::IDHash distance3 3.430000 0.020000 3.450000 ( 3.499031)
150
- DHashVips::IDHash distance 4 8.210000 0.110000 8.320000 ( 8.510735)
151
-
152
- * Ruby 2.3.8p459 (2.4.6, 2.5.5 and 2.6.3 are all similar) with newer CPU (`sysctl -n machdep.cpu.brand_string #=> Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz`):
112
+ * Ruby 2.3.8p459:
153
113
 
154
114
  load the image and calculate the fingerprint:
155
115
  user system total real
@@ -169,6 +129,19 @@ end
169
129
  DHashVips::IDHash distance3_c 0.210000 0.000000 0.210000 ( 0.212864)
170
130
  DHashVips::IDHash distance 4 8.300000 0.120000 8.420000 ( 8.499735)
171
131
 
132
+ * There is now a benchmark that runs both speed and quality tests summing results to a single table where lower numbers are better:
133
+
134
+ ruby 2.3.8p459 (2018-10-18 revision 65136) [x86_64-darwin18]
135
+ vips-8.9.2-Tue Apr 21 09:26:11 UTC 2020
136
+ Version: ImageMagick 6.9.11-24 Q16 x86_64 2020-07-18
137
+ Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
138
+
139
+ Fingerprint Compare 1/FMI^2
140
+ Phamilie 3.943 0.630 4.000
141
+ Dhash 4.969 1.097 1.375
142
+ DHash 0.434 1.089 1.556
143
+ IDHash 0.396 0.126 1.250
144
+
172
145
  * Also note that to make `#distance` able to assume the fingerprint resolution from the size of Integer that represents it, the change in its structure was needed (left half of bits was swapped with right one), so fingerprints between versions 0.0.4 and 0.0.5 became incompatible, but you probably can convert them manually. Otherwise if we put the version or structure information inside fingerprint it would became slow to (de)serialize and store.
173
146
 
174
147
  ## Development notes
data/Rakefile CHANGED
@@ -1,7 +1,11 @@
1
- STDOUT.sync = true
2
- require "pp"
1
+ begin
2
+ # for `rake release`
3
+ require "bundler/gem_tasks"
4
+ rescue LoadError
5
+ puts "consider to `gem install bundler` to be able to `rake release`"
6
+ end
3
7
 
4
- require "bundler/gem_tasks" # to push to rubygems
8
+ require "pp"
5
9
 
6
10
  visualize_hash = lambda do |hash|
7
11
  puts hash.to_s(2).rjust(64, ?0).gsub(/(?<=.)/, '\0 ').scan(/.{16}/)
@@ -346,6 +350,10 @@ task :benchmark do
346
350
  fmi
347
351
  end
348
352
 
353
+ puts RUBY_DESCRIPTION
354
+ system "vips -v"
355
+ system "identify -version | /usr/bin/head -1"
356
+ system "sysctl -n machdep.cpu.brand_string"
349
357
  require "mll"
350
358
  puts MLL::grid.call %w{ \ Fingerprint Compare 1/FMI^2 }.zip(*[
351
359
  %w{ Phamilie Dhash DHash IDHash },
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "dhash-vips"
3
- spec.version = "0.1.0.3"
3
+ spec.version = "0.1.1.0"
4
4
  spec.author = "Victor Maslov"
5
5
  spec.email = "nakilon@gmail.com"
6
- spec.summary = "dHash and IDHash powered by Vips"
6
+ spec.summary = "dHash and IDHash perceptual image hashing/fingerprinting"
7
7
  spec.homepage = "https://github.com/nakilon/dhash-vips"
8
8
  spec.license = "MIT"
9
9
 
@@ -20,12 +20,13 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "rake"
22
22
  spec.add_development_dependency "minitest"
23
- spec.add_development_dependency "get_process_mem"
24
23
 
25
24
  spec.add_development_dependency "rmagick", "~>2.16"
26
25
  spec.add_development_dependency "phamilie"
27
26
  spec.add_development_dependency "dhash"
28
27
 
28
+ spec.add_development_dependency "get_process_mem"
29
+
29
30
  spec.add_development_dependency "mll"
30
31
  spec.add_development_dependency "byebug"
31
32
  end
data/extconf.rb CHANGED
@@ -1,13 +1,17 @@
1
1
  require "mkmf"
2
2
 
3
3
  File.write "Makefile", dummy_makefile(?.).join
4
- unless Gem::Platform.local.os == "darwin" && Gem::Version.new(RUBY_VERSION) == Gem::Version.new("2.3.8")
4
+ unless Gem::Platform.local.os == "darwin" && ENV["RBENV_ROOT"] && ENV["RBENV_VERSION"]
5
5
  else
6
- begin
7
- # https://github.com/rbenv/rbenv/issues/1199
8
- append_cppflags "-I#{Dir.glob("#{`rbenv root`.chomp}/sources/#{`rbenv version-name`.chomp}/*/").first}"
9
- rescue
6
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.3.8") ||
7
+ Gem::Version.new(RUBY_VERSION) > Gem::Version.new("2.4.9")
10
8
  else
9
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4")
10
+ else
11
+ append_cppflags "-DRUBY_EXPORT"
12
+ end
13
+ # https://github.com/rbenv/rbenv/issues/1199
14
+ append_cppflags "-I#{Dir.glob("#{ENV["RBENV_ROOT"]}/sources/#{ENV["RBENV_VERSION"]}/ruby-*/").first}"
11
15
  create_makefile "idhash"
12
16
  # Why this hack?
13
17
  # 1. Because I want to use Ruby and ./idhash.bundle for tests, not C.
@@ -21,10 +25,11 @@ else
21
25
  end
22
26
 
23
27
  # Cases to check:
24
- # 0. all is ok
25
- # `rm -rf idhash.o idhash.bundle pkg && bundle exec rake install` # w/o ext # ["/Users/nakilon/_/dhash-vips/lib/dhash-vips.rb", 32]
26
- # `rm -f idhash.o idhash.bundle Makefile && ruby extconf.rb && make` # with ext # ["/Users/nakilon/_/dhash-vips/lib/dhash-vips.rb", 40]
27
- # `bundle exec rake -rdhash-vips -e "p DHashVips::IDHash.method(:distance3).source_location"`
28
+ # 0. everything is ok
29
+ # `rm -rf idhash.o idhash.bundle idhash.so pkg && bundle exec rake install`
30
+ # `bundle exec rake -rdhash-vips -e "p DHashVips::IDHash.method(:distance3).source_location"` # => # ["/Users/nakilon/_/dhash-vips/lib/dhash-vips.rb", 32] # currently falsely says that gem install failed idk why
31
+ # `rm -f idhash.o idhash.bundle idhash.so Makefile && ruby extconf.rb && make`
32
+ # `bundle exec rake -rdhash-vips -e "p DHashVips::IDHash.method(:distance3).source_location"` # => # ["/Users/nakilon/_/dhash-vips/lib/dhash-vips.rb", 53]
28
33
  # 1. not macOS && rbenv
29
34
  # 2. fail during append_cppflags
30
35
  # 3. failed compilation
@@ -20,8 +20,20 @@ ss = s.repeated_permutation(4).map do |s1, s2, s3, s4|
20
20
  end
21
21
  end
22
22
  fail unless :distance3 == DHashVips::IDHash.method(:distance3).original_name
23
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4")
24
+ check = lambda do |s1, s2|
25
+ s1.is_a?(Bignum) && s2.is_a?(Bignum)
26
+ end
27
+ else
28
+ require "rbconfig/sizeof"
29
+ check = lambda do |s1, s2|
30
+ # https://github.com/ruby/ruby/commit/de2f7416d2deb4166d78638a41037cb550d64484#diff-16b196bc6bfe8fba63951420f843cfb4R10
31
+ _FIXNUM_MAX = (1 << (8 * RbConfig::SIZEOF["long"] - 2)) - 1
32
+ s1 > _FIXNUM_MAX && s2 > _FIXNUM_MAX
33
+ end
34
+ end
23
35
  ss.product ss do |s1, s2|
24
- next unless s1.is_a?(Bignum) && s2.is_a?(Bignum)
36
+ next unless check.call s1, s2
25
37
  unless f[s1, s2] == DHashVips::IDHash.distance3_c(s1, s2)
26
38
  p [s1, s2]
27
39
  p [s1.to_s(16).rjust(64,?0)].pack("H*").unpack("N*").map{ |_| _.to_s(2).rjust(32, ?0) }
@@ -37,11 +37,25 @@ module DHashVips
37
37
  rescue LoadError
38
38
  alias_method :distance3, :distance3_ruby
39
39
  else
40
- def distance3 a, b
41
- if a.is_a?(Bignum) && b.is_a?(Bignum)
42
- distance3_c a, b
43
- else
44
- distance3_ruby a, b
40
+ # we can't just do `defined? Bignum` because it's defined but deprecated (some internal CONST_DEPRECATED flag)
41
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4")
42
+ def distance3 a, b
43
+ if a.is_a?(Bignum) && b.is_a?(Bignum)
44
+ distance3_c a, b
45
+ else
46
+ distance3_ruby a, b
47
+ end
48
+ end
49
+ else
50
+ # https://github.com/ruby/ruby/commit/de2f7416d2deb4166d78638a41037cb550d64484#diff-16b196bc6bfe8fba63951420f843cfb4R10
51
+ require "rbconfig/sizeof"
52
+ FIXNUM_MAX = (1 << (8 * RbConfig::SIZEOF["long"] - 2)) - 1
53
+ def distance3 a, b
54
+ if a > FIXNUM_MAX && b > FIXNUM_MAX
55
+ distance3_c a, b
56
+ else
57
+ distance3_ruby a, b
58
+ end
45
59
  end
46
60
  end
47
61
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dhash-vips
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.3
4
+ version: 0.1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Maslov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-25 00:00:00.000000000 Z
11
+ date: 2020-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-vips
@@ -53,35 +53,35 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: get_process_mem
56
+ name: rmagick
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '2.16'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '2.16'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rmagick
70
+ name: phamilie
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '2.16'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '2.16'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: phamilie
84
+ name: dhash
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: dhash
98
+ name: get_process_mem
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -174,9 +174,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
174
  version: '0'
175
175
  requirements: []
176
176
  rubyforge_project:
177
- rubygems_version: 2.5.2.3
177
+ rubygems_version: 2.6.14.4
178
178
  signing_key:
179
179
  specification_version: 4
180
- summary: dHash and IDHash powered by Vips
180
+ summary: dHash and IDHash perceptual image hashing/fingerprinting
181
181
  test_files:
182
182
  - test.rb