pHash 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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