pHash 1.0.2 → 1.1.0

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.
data/lib/phash.rb CHANGED
@@ -1,13 +1,23 @@
1
1
  require 'ffi'
2
2
 
3
3
  module Phash
4
- class HashData
4
+ class Data
5
5
  attr_reader :data, :length
6
6
  def initialize(data, length = nil)
7
7
  @data, @length = data, length
8
8
  end
9
9
  end
10
10
 
11
+ class HashData < Data
12
+ def similarity(other, *args)
13
+ Phash.send("#{self.class.hash_type}_similarity", self, other, *args)
14
+ end
15
+
16
+ def self.hash_type
17
+ @hash_type ||= self.name.split('::').last.sub(/Hash$/, '').downcase
18
+ end
19
+ end
20
+
11
21
  class FileHash
12
22
  attr_reader :path
13
23
 
@@ -28,8 +38,18 @@ module Phash
28
38
  @phash ||= compute_phash
29
39
  end
30
40
 
31
- def %(other)
32
- similarity(other)
41
+ def compute_phash
42
+ Phash.send("#{self.class.hash_type}_hash", @path)
43
+ end
44
+
45
+ # Similarity with other phash
46
+ def similarity(other, *args)
47
+ phash.similarity(other.phash, *args)
48
+ end
49
+ alias_method :%, :similarity
50
+
51
+ def self.hash_type
52
+ @hash_type ||= self.name.split('::').last.downcase
33
53
  end
34
54
  end
35
55
 
data/lib/phash/audio.rb CHANGED
@@ -49,23 +49,38 @@ module Phash
49
49
  #
50
50
  attach_function :ph_audio_distance_ber, [:pointer, :int, :pointer, :int, :float, :int, :pointer], :pointer, :blocking => true
51
51
 
52
- class AudioHash < HashData; end
53
52
  class << self
54
- # Read audio file specified by path and optional length using <tt>ph_readaudio</tt> and get its hash using <tt>ph_audiohash</tt>
55
- def audio_hash(path, length = 0)
56
- sample_rate = 8000
53
+ DEFAULT_SAMPLE_RATE = 8000
54
+
55
+ # Read audio file specified by path and optional length using <tt>ph_readaudio</tt>
56
+ def audio_data(path, length = 0, sample_rate = nil)
57
+ sample_rate ||= DEFAULT_SAMPLE_RATE
57
58
  audio_data_length_p = FFI::MemoryPointer.new :int
58
59
  if audio_data = ph_readaudio(path.to_s, sample_rate, 1, nil, audio_data_length_p, length.to_f)
59
60
  audio_data_length = audio_data_length_p.get_int(0)
60
61
  audio_data_length_p.free
61
62
 
62
- hash_data_length_p = FFI::MemoryPointer.new :int
63
- if hash_data = ph_audiohash(audio_data, audio_data_length, sample_rate, hash_data_length_p)
64
- hash_data_length = hash_data_length_p.get_int(0)
65
- hash_data_length_p.free
63
+ Data.new(audio_data, audio_data_length)
64
+ end
65
+ end
66
+
67
+ # Get hash of audio data using <tt>ph_audiohash</tt>
68
+ def audio_data_hash(audio_data, sample_rate = nil)
69
+ sample_rate ||= DEFAULT_SAMPLE_RATE
70
+ hash_data_length_p = FFI::MemoryPointer.new :int
71
+ if hash_data = ph_audiohash(audio_data.data, audio_data.length, sample_rate, hash_data_length_p)
72
+ hash_data_length = hash_data_length_p.get_int(0)
73
+ hash_data_length_p.free
74
+
75
+ AudioHash.new(hash_data, hash_data_length)
76
+ end
77
+ end
66
78
 
67
- AudioHash.new(hash_data, hash_data_length)
68
- end
79
+ # Use <tt>audio_data</tt> and <tt>audio_data_hash</tt> to compute hash for file at path, specify max length in seconds to read
80
+ def audio_hash(path, length = 0, sample_rate = nil)
81
+ sample_rate ||= DEFAULT_SAMPLE_RATE
82
+ if audio_data = audio_data(path, length, sample_rate)
83
+ audio_data_hash(audio_data, sample_rate)
69
84
  end
70
85
  end
71
86
 
@@ -92,6 +107,10 @@ module Phash
92
107
  end
93
108
  end
94
109
 
110
+ # Class to store audio hash and compare to other
111
+ class AudioHash < HashData
112
+ end
113
+
95
114
  # Class to store audio file hash and compare to other
96
115
  class Audio < FileHash
97
116
  attr_reader :length
@@ -101,13 +120,6 @@ module Phash
101
120
  @path, @length = path, length
102
121
  end
103
122
 
104
- # Similarity with other audio
105
- def similarity(other, *args)
106
- Phash.audio_similarity(phash, other.phash, *args)
107
- end
108
-
109
- private
110
-
111
123
  def compute_phash
112
124
  Phash.audio_hash(@path, @length)
113
125
  end
data/lib/phash/image.rb CHANGED
@@ -25,16 +25,16 @@ module Phash
25
25
  hash = hash_p.get_uint64(0)
26
26
  hash_p.free
27
27
 
28
- hash
28
+ ImageHash.new(hash)
29
29
  end
30
30
  end
31
31
 
32
32
  # Get distance between two image hashes using <tt>ph_hamming_distance</tt>
33
33
  def image_hamming_distance(hash_a, hash_b)
34
- hash_a.is_a?(Integer) or raise ArgumentError.new('hash_a is not an Integer')
35
- hash_b.is_a?(Integer) or raise ArgumentError.new('hash_b is not an Integer')
34
+ hash_a.is_a?(ImageHash) or raise ArgumentError.new('hash_a is not an ImageHash')
35
+ hash_b.is_a?(ImageHash) or raise ArgumentError.new('hash_b is not an ImageHash')
36
36
 
37
- ph_hamming_distance(hash_a, hash_b)
37
+ ph_hamming_distance(hash_a.data, hash_b.data)
38
38
  end
39
39
 
40
40
  # Get similarity from hamming_distance
@@ -43,17 +43,11 @@ module Phash
43
43
  end
44
44
  end
45
45
 
46
+ # Class to store image hash and compare to other
47
+ class ImageHash < HashData
48
+ end
49
+
46
50
  # Class to store image file hash and compare to other
47
51
  class Image < FileHash
48
- # Similarity with other image
49
- def similarity(other)
50
- Phash.image_similarity(phash, other.phash)
51
- end
52
-
53
- private
54
-
55
- def compute_phash
56
- Phash.image_hash(@path)
57
- end
58
52
  end
59
53
  end
data/lib/phash/text.rb CHANGED
@@ -35,7 +35,6 @@ module Phash
35
35
  #
36
36
  attach_function :ph_compare_text_hashes, [:pointer, :int, :pointer, :int, :pointer], :pointer, :blocking => true
37
37
 
38
- class TextHash < HashData; end
39
38
  class << self
40
39
  # Get text file hash using <tt>ph_texthash</tt>
41
40
  def text_hash(path)
@@ -66,7 +65,6 @@ module Phash
66
65
 
67
66
  def text_similarity(hash_a, hash_b)
68
67
  matches = text_hash_matches(hash_a, hash_b)
69
- # p [hash_a.length, hash_b.length, matches.length]
70
68
  matched_a = Array.new(hash_a.length)
71
69
  matched_b = Array.new(hash_b.length)
72
70
  matches.each do |match|
@@ -83,17 +81,11 @@ module Phash
83
81
  end
84
82
  end
85
83
 
84
+ # Class to store text hash and compare to other
85
+ class TextHash < HashData
86
+ end
87
+
86
88
  # Class to store text file hash and compare to other
87
89
  class Text < FileHash
88
- # Distance from other file, for now bit useless thing
89
- def similarity(other)
90
- Phash.text_similarity(phash, other.phash)
91
- end
92
-
93
- private
94
-
95
- def compute_phash
96
- Phash.text_hash(@path)
97
- end
98
90
  end
99
91
  end
data/lib/phash/video.rb CHANGED
@@ -13,7 +13,6 @@ module Phash
13
13
  #
14
14
  attach_function :ph_dct_videohash_dist, [:pointer, :int, :pointer, :int, :int], :double, :blocking => true
15
15
 
16
- class VideoHash < HashData; end
17
16
  class << self
18
17
  # Get video hash using <tt>ph_dct_videohash</tt>
19
18
  def video_hash(path)
@@ -38,17 +37,11 @@ module Phash
38
37
  alias_method :video_similarity, :video_dct_distance
39
38
  end
40
39
 
40
+ # Class to store video hash and compare to other
41
+ class VideoHash < HashData
42
+ end
43
+
41
44
  # Class to store video file hash and compare to other
42
45
  class Video < FileHash
43
- # Similarity with other video
44
- def similarity(other, *args)
45
- Phash.video_similarity(phash, other.phash, *args)
46
- end
47
-
48
- private
49
-
50
- def compute_phash
51
- Phash.video_hash(@path)
52
- end
53
46
  end
54
47
  end
data/pHash.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'pHash'
5
- s.version = '1.0.2'
5
+ s.version = '1.1.0'
6
6
  s.summary = %q{Use pHash with ruby}
7
7
  s.homepage = "http://github.com/toy/#{s.name}"
8
8
  s.authors = ['Ivan Kuchin']
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 2
10
- version: 1.0.2
10
+ version: 1.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ivan Kuchin
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-12-26 00:00:00 Z
18
+ date: 2011-12-27 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rspec