grayphash 0.0.5 → 0.0.6
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/ext/{grayhash → grayphash}/extconf.rb +0 -0
- data/ext/grayphash/grayphash.cpp +128 -0
- data/lib/grayphash.rb +0 -1
- metadata +4 -3
|
File without changes
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
#include <CImg.h>
|
|
3
|
+
using namespace cimg_library;
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// Use this typedef to make the compiler happy when
|
|
7
|
+
// calling rb_define_method()
|
|
8
|
+
typedef VALUE (ruby_method)(...);
|
|
9
|
+
typedef unsigned long long ulong64;
|
|
10
|
+
|
|
11
|
+
extern "C" VALUE t_init(VALUE self, VALUE file)
|
|
12
|
+
{
|
|
13
|
+
Check_Type(file, T_STRING);
|
|
14
|
+
rb_iv_set(self, "@file", file);
|
|
15
|
+
|
|
16
|
+
return self;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
extern "C" VALUE t_about(VALUE self)
|
|
20
|
+
{
|
|
21
|
+
return rb_str_new_cstr("pHash 0.9.4. Copyright 2008-2010 Aetilius, Inc. Included only some image functions (grayphash v-0.0.4.3).");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
CImg<float>* ph_dct_matrix(const int N){
|
|
26
|
+
CImg<float> *ptr_matrix = new CImg<float>(N,N,1,1,1/sqrt((float)N));
|
|
27
|
+
const float c1 = sqrt(2.0/N);
|
|
28
|
+
for (int x=0;x<N;x++){
|
|
29
|
+
for (int y=1;y<N;y++){
|
|
30
|
+
*ptr_matrix->data(x,y) = c1*cos((cimg::PI/2/N)*y*(2*x+1));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return ptr_matrix;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
int ph_dct_imagehash(const char* file,ulong64 &hash){
|
|
37
|
+
|
|
38
|
+
if (!file){
|
|
39
|
+
return -1;
|
|
40
|
+
}
|
|
41
|
+
CImg<uint8_t> src;
|
|
42
|
+
try {
|
|
43
|
+
src.load(file);
|
|
44
|
+
} catch (CImgIOException ex){
|
|
45
|
+
return -1;
|
|
46
|
+
}
|
|
47
|
+
CImg<float> meanfilter(7,7,1,1,1);
|
|
48
|
+
CImg<float> img;
|
|
49
|
+
if (src.spectrum() == 3){
|
|
50
|
+
img = src.RGBtoYCbCr().channel(0).get_convolve(meanfilter);
|
|
51
|
+
} else if (src.spectrum() == 4){
|
|
52
|
+
int width = img.width();
|
|
53
|
+
int height = img.height();
|
|
54
|
+
int depth = img.depth();
|
|
55
|
+
img = src.crop(0,0,0,0,width-1,height-1,depth-1,2).RGBtoYCbCr().channel(0).get_convolve(meanfilter);
|
|
56
|
+
} else {
|
|
57
|
+
img = src.channel(0).get_convolve(meanfilter);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
img.resize(32,32);
|
|
61
|
+
CImg<float> *C = ph_dct_matrix(32);
|
|
62
|
+
CImg<float> Ctransp = C->get_transpose();
|
|
63
|
+
|
|
64
|
+
CImg<float> dctImage = (*C)*img*Ctransp;
|
|
65
|
+
|
|
66
|
+
CImg<float> subsec = dctImage.crop(1,1,8,8).unroll('x');;
|
|
67
|
+
|
|
68
|
+
float median = subsec.median();
|
|
69
|
+
ulong64 one = 0x0000000000000001;
|
|
70
|
+
hash = 0x0000000000000000;
|
|
71
|
+
for (int i=0;i< 64;i++){
|
|
72
|
+
float current = subsec(i);
|
|
73
|
+
if (current > median)
|
|
74
|
+
hash |= one;
|
|
75
|
+
one = one << 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
delete C;
|
|
79
|
+
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
extern "C" VALUE t_phash(VALUE self) {
|
|
84
|
+
VALUE lfile = rb_iv_get(self, "@file");
|
|
85
|
+
char* file = RSTRING_PTR(lfile);
|
|
86
|
+
ulong64 phash = 0;
|
|
87
|
+
ph_dct_imagehash(file, phash);
|
|
88
|
+
|
|
89
|
+
if(phash==0)
|
|
90
|
+
rb_raise(rb_eFatal, "PHash cannot be 0 but it calcutaled as it. Probably you load PNG file with transparency.");
|
|
91
|
+
|
|
92
|
+
rb_iv_set(self, "@phash", ULL2NUM(phash));
|
|
93
|
+
|
|
94
|
+
return ULL2NUM(phash);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
extern "C" VALUE t_hamming(VALUE self, VALUE phash1, VALUE phash2) {
|
|
100
|
+
Check_Type(phash1, T_BIGNUM);
|
|
101
|
+
Check_Type(phash2, T_BIGNUM);
|
|
102
|
+
|
|
103
|
+
ulong64 hash1 = rb_num2ull(phash1);
|
|
104
|
+
ulong64 hash2 = rb_num2ull(phash2);
|
|
105
|
+
|
|
106
|
+
ulong64 x = hash1^hash2;
|
|
107
|
+
const ulong64 m1 = 0x5555555555555555ULL;
|
|
108
|
+
const ulong64 m2 = 0x3333333333333333ULL;
|
|
109
|
+
const ulong64 h01 = 0x0101010101010101ULL;
|
|
110
|
+
const ulong64 m4 = 0x0f0f0f0f0f0f0f0fULL;
|
|
111
|
+
x -= (x >> 1) & m1;
|
|
112
|
+
x = (x & m2) + ((x >> 2) & m2);
|
|
113
|
+
x = (x + (x >> 4)) & m4;
|
|
114
|
+
return INT2NUM((x * h01)>>56);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
VALUE Grayphash;
|
|
119
|
+
|
|
120
|
+
extern "C" void Init_grayphash()
|
|
121
|
+
{
|
|
122
|
+
Grayphash = rb_define_class("Grayphash", rb_cObject);
|
|
123
|
+
rb_define_method(Grayphash, "initialize", (ruby_method*) &t_init, 1);
|
|
124
|
+
rb_define_method(Grayphash, "about", (ruby_method*) &t_about, 0);
|
|
125
|
+
rb_define_method(Grayphash, "phash", (ruby_method*) &t_phash, 0);
|
|
126
|
+
rb_define_method(Grayphash, "hamming", (ruby_method*) &t_hamming, 2);
|
|
127
|
+
}
|
|
128
|
+
|
data/lib/grayphash.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: grayphash
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.6
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -15,11 +15,12 @@ description: pHash image wrapper
|
|
|
15
15
|
email: tauraloke@gmail.com
|
|
16
16
|
executables: []
|
|
17
17
|
extensions:
|
|
18
|
-
- ext/
|
|
18
|
+
- ext/grayphash/extconf.rb
|
|
19
19
|
extra_rdoc_files: []
|
|
20
20
|
files:
|
|
21
21
|
- lib/grayphash.rb
|
|
22
|
-
- ext/
|
|
22
|
+
- ext/grayphash/grayphash.cpp
|
|
23
|
+
- ext/grayphash/extconf.rb
|
|
23
24
|
homepage: http://github.com/tauraloke/grayphash
|
|
24
25
|
licenses:
|
|
25
26
|
- GPL
|