Linux ip-172-26-7-228 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64
Apache
: 172.26.7.228 | : 18.117.184.236
Cant Read [ /etc/named.conf ]
5.6.40-24+ubuntu18.04.1+deb.sury.org+1
www-data
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
HASH IDENTIFIER
README
+ Create Folder
+ Create File
/
home /
ubuntu /
ImageMagick-7.0.10-22 /
MagickCore /
[ HOME SHELL ]
Name
Size
Permission
Action
.deps
[ DIR ]
drwxrwxr-x
.libs
[ DIR ]
drwxrwxr-x
.dirstamp
0
B
-rw-rw-r--
ImageMagick-7.Q16HDRI.pc
867
B
-rw-rw-r--
ImageMagick.pc
867
B
-rw-rw-r--
ImageMagick.pc.in
575
B
-rw-rw-r--
MagickCore-7.Q16HDRI.pc
916
B
-rw-rw-r--
MagickCore-config
1.5
KB
-rwxrwxr-x
MagickCore-config.1
1.85
KB
-rw-rw-r--
MagickCore-config.in
1.57
KB
-rw-rw-r--
MagickCore.h
4.94
KB
-rw-rw-r--
MagickCore.pc
916
B
-rw-rw-r--
MagickCore.pc.in
688
B
-rw-rw-r--
Makefile.am
14.76
KB
-rw-rw-r--
accelerate-kernels-private.h
102.16
KB
-rw-rw-r--
accelerate-private.h
2.63
KB
-rw-rw-r--
accelerate.c
169.72
KB
-rw-rw-r--
animate-private.h
1.23
KB
-rw-rw-r--
animate.c
103.29
KB
-rw-rw-r--
animate.h
979
B
-rw-rw-r--
annotate-private.h
1022
B
-rw-rw-r--
annotate.c
71.69
KB
-rw-rw-r--
annotate.h
1.26
KB
-rw-rw-r--
artifact.c
18.74
KB
-rw-rw-r--
artifact.h
1.35
KB
-rw-rw-r--
attribute.c
69.33
KB
-rw-rw-r--
attribute.h
1.78
KB
-rw-rw-r--
blob-private.h
4.07
KB
-rw-rw-r--
blob.c
207.68
KB
-rw-rw-r--
blob.h
3.29
KB
-rw-rw-r--
cache-private.h
6.63
KB
-rw-rw-r--
cache-view.c
44.83
KB
-rw-rw-r--
cache-view.h
3.63
KB
-rw-rw-r--
cache.c
211.11
KB
-rw-rw-r--
cache.h
2.5
KB
-rw-rw-r--
channel.c
41.69
KB
-rw-rw-r--
channel.h
1.28
KB
-rw-rw-r--
cipher.c
40.58
KB
-rw-rw-r--
cipher.h
1.11
KB
-rw-rw-r--
client.c
7.37
KB
-rw-rw-r--
client.h
1.03
KB
-rw-rw-r--
coder-private.h
1005
B
-rw-rw-r--
coder.c
20.03
KB
-rw-rw-r--
coder.h
1.28
KB
-rw-rw-r--
color-private.h
2.28
KB
-rw-rw-r--
color.c
105.5
KB
-rw-rw-r--
color.h
2.22
KB
-rw-rw-r--
colormap-private.h
1.8
KB
-rw-rw-r--
colormap.c
13.3
KB
-rw-rw-r--
colormap.h
1.05
KB
-rw-rw-r--
colorspace-private.h
4.23
KB
-rw-rw-r--
colorspace.c
99.03
KB
-rw-rw-r--
colorspace.h
2.35
KB
-rw-rw-r--
compare.c
72.32
KB
-rw-rw-r--
compare.h
1.86
KB
-rw-rw-r--
composite-private.h
5.5
KB
-rw-rw-r--
composite.c
81.18
KB
-rw-rw-r--
composite.h
2.85
KB
-rw-rw-r--
compress.c
39.93
KB
-rw-rw-r--
compress.h
2.15
KB
-rw-rw-r--
configure-private.h
1019
B
-rw-rw-r--
configure.c
44.68
KB
-rw-rw-r--
configure.h
1.65
KB
-rw-rw-r--
constitute-private.h
890
B
-rw-rw-r--
constitute.c
50.54
KB
-rw-rw-r--
constitute.h
1.45
KB
-rw-rw-r--
decorate.c
31.1
KB
-rw-rw-r--
decorate.h
1.34
KB
-rw-rw-r--
delegate-private.h
2.16
KB
-rw-rw-r--
delegate.c
83.77
KB
-rw-rw-r--
delegate.h
1.98
KB
-rw-rw-r--
deprecate.c
13.45
KB
-rw-rw-r--
deprecate.h
1.21
KB
-rw-rw-r--
display-private.h
1.24
KB
-rw-rw-r--
display.c
515.56
KB
-rw-rw-r--
display.h
1.05
KB
-rw-rw-r--
distort.c
134.29
KB
-rw-rw-r--
distort.h
2.65
KB
-rw-rw-r--
distribute-cache-private.h
2.24
KB
-rw-rw-r--
distribute-cache.c
49.1
KB
-rw-rw-r--
distribute-cache.h
997
B
-rw-rw-r--
draw-private.h
2.1
KB
-rw-rw-r--
draw.c
245.29
KB
-rw-rw-r--
draw.h
5.55
KB
-rw-rw-r--
effect.c
125.86
KB
-rw-rw-r--
effect.h
2.85
KB
-rw-rw-r--
enhance.c
137.51
KB
-rw-rw-r--
enhance.h
2.32
KB
-rw-rw-r--
exception-private.h
3.18
KB
-rw-rw-r--
exception.c
44.49
KB
-rw-rw-r--
exception.h
4.35
KB
-rw-rw-r--
feature.c
83.79
KB
-rw-rw-r--
feature.h
1.7
KB
-rw-rw-r--
fourier.c
49.36
KB
-rw-rw-r--
fourier.h
1.38
KB
-rw-rw-r--
fx-private.h
1.21
KB
-rw-rw-r--
fx.c
87.87
KB
-rw-rw-r--
fx.h
956
B
-rw-rw-r--
gem-private.h
6.28
KB
-rw-rw-r--
gem.c
53.31
KB
-rw-rw-r--
gem.h
1.15
KB
-rw-rw-r--
geometry.c
55.44
KB
-rw-rw-r--
geometry.h
3.98
KB
-rw-rw-r--
histogram.c
39.72
KB
-rw-rw-r--
histogram.h
1.35
KB
-rw-rw-r--
identify.c
57.07
KB
-rw-rw-r--
identify.h
971
B
-rw-rw-r--
image-private.h
2.89
KB
-rw-rw-r--
image-view.c
42.98
KB
-rw-rw-r--
image-view.h
2.72
KB
-rw-rw-r--
image.c
142.86
KB
-rw-rw-r--
image.h
13.87
KB
-rw-rw-r--
layer.c
75.49
KB
-rw-rw-r--
layer.h
2
KB
-rw-rw-r--
libMagickCore-7.Q16HDRI.la
1.32
KB
-rw-rw-r--
libMagickCore.map
46
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-acc...
374
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-acc...
6.25
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ani...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ani...
245.7
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ann...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ann...
225.34
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-art...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-art...
57.34
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-att...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-att...
198.58
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-blo...
356
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-blo...
559.89
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cac...
374
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cac...
130.77
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cac...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cac...
575.03
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cha...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cha...
132.27
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cip...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cip...
99.63
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cli...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cli...
11.99
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cod...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-cod...
48.66
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-col...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-col...
187.05
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-col...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-col...
64.29
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-col...
374
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-col...
416.23
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-com...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-com...
244.2
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-com...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-com...
205.62
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-com...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-com...
116.91
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-con...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-con...
92.49
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-con...
374
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-con...
134.21
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dec...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dec...
140.39
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-del...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-del...
181.88
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dep...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dep...
40.1
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dis...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dis...
1001.06
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dis...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dis...
257.94
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dis...
392
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dis...
138.98
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dra...
356
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-dra...
629.21
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-eff...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-eff...
359.09
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-enh...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-enh...
435.72
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-exc...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-exc...
79.98
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-fea...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-fea...
231.75
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-fou...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-fou...
147.25
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-fx....
350
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-fx....
285.02
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-gem...
353
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-gem...
222.46
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-geo...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-geo...
111.41
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-his...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-his...
103.51
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ide...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ide...
183.14
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ima...
374
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ima...
103.35
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ima...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ima...
311.29
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-lay...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-lay...
140.62
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-lin...
377
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-lin...
41.23
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-lis...
356
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-lis...
137.44
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-loc...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-loc...
93.1
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-log...
353
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-log...
109.05
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mag...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mag...
54.52
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mag...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mag...
123.44
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mat...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mat...
90.06
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mem...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mem...
64.4
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mim...
356
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mim...
69.73
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mod...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mod...
46.27
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mon...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mon...
37.7
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mon...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mon...
102.55
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mor...
374
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-mor...
249.84
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ope...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ope...
14.32
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-opt...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-opt...
238.09
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pai...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pai...
158.05
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pix...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pix...
1.12
MB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pol...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pol...
84.46
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pre...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pre...
50.55
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pro...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pro...
178.05
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pro...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-pro...
375.58
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-qua...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-qua...
308.11
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-qua...
386
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-qua...
886.72
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-qua...
386
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-qua...
690.47
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-qua...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-qua...
93.22
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ran...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ran...
71.95
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-reg...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-reg...
58.8
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-res...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-res...
101.68
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-res...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-res...
484.14
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-res...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-res...
130.89
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-seg...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-seg...
137.09
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-sem...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-sem...
27.5
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-she...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-she...
209.97
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-sig...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-sig...
77.59
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-spl...
374
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-spl...
71.54
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-sta...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-sta...
42.69
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-sta...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-sta...
361.96
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-str...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-str...
389.89
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-str...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-str...
145.78
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-thr...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-thr...
9.66
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-thr...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-thr...
223.15
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-tim...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-tim...
38.76
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-tok...
359
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-tok...
220.66
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-tra...
371
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-tra...
228.2
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-typ...
356
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-typ...
88.52
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-uti...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-uti...
121.42
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ver...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-ver...
27.84
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-vis...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-vis...
161.29
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-vis...
386
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-vis...
490.88
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-wid...
362
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-wid...
450.54
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-xml...
368
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-xml...
166.75
KB
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-xwi...
365
B
-rw-rw-r--
libMagickCore_7_Q16HDRI_la-xwi...
641.91
KB
-rw-rw-r--
linked-list.c
33.55
KB
-rw-rw-r--
linked-list.h
1.92
KB
-rw-rw-r--
list.c
52.79
KB
-rw-rw-r--
list.h
2.3
KB
-rw-rw-r--
locale-private.h
1.35
KB
-rw-rw-r--
locale.c
58.89
KB
-rw-rw-r--
locale_.h
2.2
KB
-rw-rw-r--
log-private.h
1
KB
-rw-rw-r--
log.c
56.53
KB
-rw-rw-r--
log.h
2.73
KB
-rw-rw-r--
magic-private.h
999
B
-rw-rw-r--
magic.c
27.52
KB
-rw-rw-r--
magic.h
1.32
KB
-rw-rw-r--
magick-baseconfig.h
44.5
KB
-rw-rw-r--
magick-config.h
8.75
KB
-rw-rw-r--
magick-private.h
1.04
KB
-rw-rw-r--
magick-type.h
5.78
KB
-rw-rw-r--
magick.c
66.91
KB
-rw-rw-r--
magick.h
4.18
KB
-rw-rw-r--
matrix-private.h
1.1
KB
-rw-rw-r--
matrix.c
38.14
KB
-rw-rw-r--
matrix.h
1.53
KB
-rw-rw-r--
memory-private.h
1.49
KB
-rw-rw-r--
memory.c
51.43
KB
-rw-rw-r--
memory_.h
3.24
KB
-rw-rw-r--
method-attribute.h
4.03
KB
-rw-rw-r--
methods-private.h
0
B
-rw-rw-r--
methods.h
79.51
KB
-rw-rw-r--
mime-private.h
1.07
KB
-rw-rw-r--
mime.c
35.56
KB
-rw-rw-r--
mime.h
1.38
KB
-rw-rw-r--
module-private.h
1.05
KB
-rw-rw-r--
module.c
56.79
KB
-rw-rw-r--
module.h
1.99
KB
-rw-rw-r--
monitor-private.h
1023
B
-rw-rw-r--
monitor.c
10.83
KB
-rw-rw-r--
monitor.h
1.56
KB
-rw-rw-r--
montage.c
32.5
KB
-rw-rw-r--
montage.h
1.78
KB
-rw-rw-r--
morphology-private.h
1.17
KB
-rw-rw-r--
morphology.c
177.3
KB
-rw-rw-r--
morphology.h
4.45
KB
-rw-rw-r--
mutex.h
3.03
KB
-rw-rw-r--
nt-base-private.h
3.26
KB
-rw-rw-r--
nt-base.c
90.09
KB
-rw-rw-r--
nt-base.h
8.03
KB
-rw-rw-r--
nt-feature.c
13.72
KB
-rw-rw-r--
nt-feature.h
1.11
KB
-rw-rw-r--
opencl-private.h
14.79
KB
-rw-rw-r--
opencl.c
104.16
KB
-rw-rw-r--
opencl.h
1.98
KB
-rw-rw-r--
option-private.h
872
B
-rw-rw-r--
option.c
168.81
KB
-rw-rw-r--
option.h
6.26
KB
-rw-rw-r--
paint.c
42.91
KB
-rw-rw-r--
paint.h
1.62
KB
-rw-rw-r--
pixel-accessor.h
28.36
KB
-rw-rw-r--
pixel-private.h
869
B
-rw-rw-r--
pixel.c
202.86
KB
-rw-rw-r--
pixel.h
7.18
KB
-rw-rw-r--
policy-private.h
1.22
KB
-rw-rw-r--
policy.c
41.97
KB
-rw-rw-r--
policy.h
1.88
KB
-rw-rw-r--
prepress.c
6.08
KB
-rw-rw-r--
prepress.h
939
B
-rw-rw-r--
profile-private.h
984
B
-rw-rw-r--
profile.c
85.4
KB
-rw-rw-r--
profile.h
1.64
KB
-rw-rw-r--
property.c
148.71
KB
-rw-rw-r--
property.h
1.66
KB
-rw-rw-r--
quantize.c
133.36
KB
-rw-rw-r--
quantize.h
2.05
KB
-rw-rw-r--
quantum-export.c
124.46
KB
-rw-rw-r--
quantum-import.c
145.28
KB
-rw-rw-r--
quantum-private.h
19.37
KB
-rw-rw-r--
quantum.c
38.9
KB
-rw-rw-r--
quantum.h
5.1
KB
-rw-rw-r--
random-private.h
2.16
KB
-rw-rw-r--
random.c
33.01
KB
-rw-rw-r--
random_.h
1.49
KB
-rw-rw-r--
registry-private.h
1014
B
-rw-rw-r--
registry.c
18.63
KB
-rw-rw-r--
registry.h
1.41
KB
-rw-rw-r--
resample-private.h
2.21
KB
-rw-rw-r--
resample.c
56.74
KB
-rw-rw-r--
resample.h
2.72
KB
-rw-rw-r--
resize-private.h
2.02
KB
-rw-rw-r--
resize.c
149.98
KB
-rw-rw-r--
resize.h
1.71
KB
-rw-rw-r--
resource-private.h
1.11
KB
-rw-rw-r--
resource.c
47.74
KB
-rw-rw-r--
resource_.h
1.69
KB
-rw-rw-r--
segment.c
60.41
KB
-rw-rw-r--
segment.h
1.09
KB
-rw-rw-r--
semaphore-private.h
1009
B
-rw-rw-r--
semaphore.c
16.58
KB
-rw-rw-r--
semaphore.h
1.15
KB
-rw-rw-r--
shear.c
56.66
KB
-rw-rw-r--
shear.h
1.11
KB
-rw-rw-r--
signature-private.h
1.5
KB
-rw-rw-r--
signature.c
28.84
KB
-rw-rw-r--
signature.h
947
B
-rw-rw-r--
splay-tree.c
54.92
KB
-rw-rw-r--
splay-tree.h
1.98
KB
-rw-rw-r--
static.c
13.23
KB
-rw-rw-r--
static.h
10.11
KB
-rw-rw-r--
statistic.c
91.04
KB
-rw-rw-r--
statistic.h
4.25
KB
-rw-rw-r--
stream-private.h
1.04
KB
-rw-rw-r--
stream.c
97.33
KB
-rw-rw-r--
stream.h
1.57
KB
-rw-rw-r--
string-private.h
3.17
KB
-rw-rw-r--
string.c
90.27
KB
-rw-rw-r--
string_.h
3.61
KB
-rw-rw-r--
studio.h
9.23
KB
-rw-rw-r--
thread-private.h
3.87
KB
-rw-rw-r--
thread.c
9.62
KB
-rw-rw-r--
thread_.h
1.59
KB
-rw-rw-r--
threshold.c
81.92
KB
-rw-rw-r--
threshold.h
2.01
KB
-rw-rw-r--
timer-private.h
1.53
KB
-rw-rw-r--
timer.c
21.71
KB
-rw-rw-r--
timer.h
1.57
KB
-rw-rw-r--
token-private.h
4.27
KB
-rw-rw-r--
token.c
30.01
KB
-rw-rw-r--
token.h
1.48
KB
-rw-rw-r--
transform-private.h
997
B
-rw-rw-r--
transform.c
78.58
KB
-rw-rw-r--
transform.h
1.76
KB
-rw-rw-r--
type-private.h
1000
B
-rw-rw-r--
type.c
44.45
KB
-rw-rw-r--
type.h
1.94
KB
-rw-rw-r--
utility-private.h
7.37
KB
-rw-rw-r--
utility.c
60.19
KB
-rw-rw-r--
utility.h
1.62
KB
-rw-rw-r--
version-private.h
984
B
-rw-rw-r--
version.c
22.62
KB
-rw-rw-r--
version.h
3.02
KB
-rw-rw-r--
version.h.in
3.29
KB
-rw-rw-r--
vision.c
49.74
KB
-rw-rw-r--
vision.h
1.22
KB
-rw-rw-r--
visual-effects.c
122.12
KB
-rw-rw-r--
visual-effects.h
2.81
KB
-rw-rw-r--
widget-private.h
2.59
KB
-rw-rw-r--
widget.c
320.79
KB
-rw-rw-r--
widget.h
852
B
-rw-rw-r--
xml-tree-private.h
1.62
KB
-rw-rw-r--
xml-tree.c
93.09
KB
-rw-rw-r--
xml-tree.h
1.46
KB
-rw-rw-r--
xwindow-private.h
11.19
KB
-rw-rw-r--
xwindow.c
338.16
KB
-rw-rw-r--
xwindow.h
1.11
KB
-rw-rw-r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : compare.c
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % CCCC OOO M M PPPP AAA RRRR EEEEE % % C O O MM MM P P A A R R E % % C O O M M M PPPP AAAAA RRRR EEE % % C O O M M P A A R R E % % CCCC OOO M M P A A R R EEEEE % % % % % % MagickCore Image Comparison Methods % % % % Software Design % % Cristy % % December 2003 % % % % % % Copyright 1999-2020 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % % obtain a copy of the License at % % % % https://imagemagick.org/script/license.php % % % % Unless required by applicable law or agreed to in writing, software % % distributed under the License is distributed on an "AS IS" BASIS, % % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % % See the License for the specific language governing permissions and % % limitations under the License. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % */ /* Include declarations. */ #include "MagickCore/studio.h" #include "MagickCore/artifact.h" #include "MagickCore/attribute.h" #include "MagickCore/cache-view.h" #include "MagickCore/channel.h" #include "MagickCore/client.h" #include "MagickCore/color.h" #include "MagickCore/color-private.h" #include "MagickCore/colorspace.h" #include "MagickCore/colorspace-private.h" #include "MagickCore/compare.h" #include "MagickCore/composite-private.h" #include "MagickCore/constitute.h" #include "MagickCore/exception-private.h" #include "MagickCore/geometry.h" #include "MagickCore/image-private.h" #include "MagickCore/list.h" #include "MagickCore/log.h" #include "MagickCore/memory_.h" #include "MagickCore/monitor.h" #include "MagickCore/monitor-private.h" #include "MagickCore/option.h" #include "MagickCore/pixel-accessor.h" #include "MagickCore/property.h" #include "MagickCore/resource_.h" #include "MagickCore/string_.h" #include "MagickCore/statistic.h" #include "MagickCore/string-private.h" #include "MagickCore/thread-private.h" #include "MagickCore/transform.h" #include "MagickCore/utility.h" #include "MagickCore/version.h" /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % C o m p a r e I m a g e s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % CompareImages() compares one or more pixel channels of an image to a % reconstructed image and returns the difference image. % % The format of the CompareImages method is: % % Image *CompareImages(const Image *image,const Image *reconstruct_image, % const MetricType metric,double *distortion,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the image. % % o reconstruct_image: the reconstruct image. % % o metric: the metric. % % o distortion: the computed distortion between the images. % % o exception: return any errors or warnings in this structure. % */ static size_t GetImageChannels(const Image *image) { register ssize_t i; size_t channels; channels=0; for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits & UpdatePixelTrait) != 0) channels++; } return(channels == 0 ? (size_t) 1 : channels); } MagickExport Image *CompareImages(Image *image,const Image *reconstruct_image, const MetricType metric,double *distortion,ExceptionInfo *exception) { CacheView *highlight_view, *image_view, *reconstruct_view; const char *artifact; double fuzz; Image *clone_image, *difference_image, *highlight_image; MagickBooleanType status; PixelInfo highlight, lowlight, masklight; RectangleInfo geometry; size_t columns, rows; ssize_t y; assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(reconstruct_image != (const Image *) NULL); assert(reconstruct_image->signature == MagickCoreSignature); assert(distortion != (double *) NULL); *distortion=0.0; if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=GetImageDistortion(image,reconstruct_image,metric,distortion, exception); if (status == MagickFalse) return((Image *) NULL); columns=MagickMax(image->columns,reconstruct_image->columns); rows=MagickMax(image->rows,reconstruct_image->rows); SetGeometry(image,&geometry); geometry.width=columns; geometry.height=rows; clone_image=CloneImage(image,0,0,MagickTrue,exception); if (clone_image == (Image *) NULL) return((Image *) NULL); (void) SetImageMask(clone_image,ReadPixelMask,(Image *) NULL,exception); difference_image=ExtentImage(clone_image,&geometry,exception); clone_image=DestroyImage(clone_image); if (difference_image == (Image *) NULL) return((Image *) NULL); (void) SetImageAlphaChannel(difference_image,OpaqueAlphaChannel,exception); highlight_image=CloneImage(image,columns,rows,MagickTrue,exception); if (highlight_image == (Image *) NULL) { difference_image=DestroyImage(difference_image); return((Image *) NULL); } status=SetImageStorageClass(highlight_image,DirectClass,exception); if (status == MagickFalse) { difference_image=DestroyImage(difference_image); highlight_image=DestroyImage(highlight_image); return((Image *) NULL); } (void) SetImageMask(highlight_image,ReadPixelMask,(Image *) NULL,exception); (void) SetImageAlphaChannel(highlight_image,OpaqueAlphaChannel,exception); (void) QueryColorCompliance("#f1001ecc",AllCompliance,&highlight,exception); artifact=GetImageArtifact(image,"compare:highlight-color"); if (artifact != (const char *) NULL) (void) QueryColorCompliance(artifact,AllCompliance,&highlight,exception); (void) QueryColorCompliance("#ffffffcc",AllCompliance,&lowlight,exception); artifact=GetImageArtifact(image,"compare:lowlight-color"); if (artifact != (const char *) NULL) (void) QueryColorCompliance(artifact,AllCompliance,&lowlight,exception); (void) QueryColorCompliance("#888888cc",AllCompliance,&masklight,exception); artifact=GetImageArtifact(image,"compare:masklight-color"); if (artifact != (const char *) NULL) (void) QueryColorCompliance(artifact,AllCompliance,&masklight,exception); /* Generate difference image. */ status=MagickTrue; fuzz=(double) MagickMin(GetPixelChannels(image), GetPixelChannels(reconstruct_image))* GetFuzzyColorDistance(image,reconstruct_image); image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); highlight_view=AcquireAuthenticCacheView(highlight_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(status) \ magick_number_threads(image,highlight_image,rows,1) #endif for (y=0; y < (ssize_t) rows; y++) { MagickBooleanType sync; register const Quantum *magick_restrict p, *magick_restrict q; register Quantum *magick_restrict r; register ssize_t x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); r=QueueCacheViewAuthenticPixels(highlight_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL) || (r == (Quantum *) NULL)) { status=MagickFalse; continue; } for (x=0; x < (ssize_t) columns; x++) { double Da, distance, Sa; MagickStatusType difference; register ssize_t i; if ((GetPixelReadMask(image,p) <= (QuantumRange/2)) || (GetPixelReadMask(reconstruct_image,q) <= (QuantumRange/2))) { SetPixelViaPixelInfo(highlight_image,&masklight,r); p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); r+=GetPixelChannels(highlight_image); continue; } difference=MagickFalse; distance=0.0; Sa=QuantumScale*GetPixelAlpha(image,p); Da=QuantumScale*GetPixelAlpha(reconstruct_image,q); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double pixel; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; if (channel == AlphaPixelChannel) pixel=(double) p[i]-GetPixelChannel(reconstruct_image,channel,q); else pixel=Sa*p[i]-Da*GetPixelChannel(reconstruct_image,channel,q); distance+=pixel*pixel; if (distance >= fuzz) { difference=MagickTrue; break; } } if (difference == MagickFalse) SetPixelViaPixelInfo(highlight_image,&lowlight,r); else SetPixelViaPixelInfo(highlight_image,&highlight,r); p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); r+=GetPixelChannels(highlight_image); } sync=SyncCacheViewAuthenticPixels(highlight_view,exception); if (sync == MagickFalse) status=MagickFalse; } highlight_view=DestroyCacheView(highlight_view); reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); (void) CompositeImage(difference_image,highlight_image,image->compose, MagickTrue,0,0,exception); highlight_image=DestroyImage(highlight_image); if (status == MagickFalse) difference_image=DestroyImage(difference_image); return(difference_image); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t I m a g e D i s t o r t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetImageDistortion() compares one or more pixel channels of an image to a % reconstructed image and returns the specified distortion metric. % % The format of the GetImageDistortion method is: % % MagickBooleanType GetImageDistortion(const Image *image, % const Image *reconstruct_image,const MetricType metric, % double *distortion,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the image. % % o reconstruct_image: the reconstruct image. % % o metric: the metric. % % o distortion: the computed distortion between the images. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType GetAbsoluteDistortion(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { CacheView *image_view, *reconstruct_view; double fuzz; MagickBooleanType status; size_t columns, rows; ssize_t y; /* Compute the absolute difference in pixels between two images. */ status=MagickTrue; fuzz=(double) MagickMin(GetPixelChannels(image), GetPixelChannels(reconstruct_image))* GetFuzzyColorDistance(image,reconstruct_image); rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(status) \ magick_number_threads(image,image,rows,1) #endif for (y=0; y < (ssize_t) rows; y++) { double channel_distortion[MaxPixelChannels+1]; register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t j, x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL)) { status=MagickFalse; continue; } (void) memset(channel_distortion,0,sizeof(channel_distortion)); for (x=0; x < (ssize_t) columns; x++) { double Da, distance, Sa; MagickBooleanType difference; register ssize_t i; if ((GetPixelReadMask(image,p) <= (QuantumRange/2)) || (GetPixelReadMask(reconstruct_image,q) <= (QuantumRange/2))) { p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); continue; } difference=MagickFalse; distance=0.0; Sa=QuantumScale*GetPixelAlpha(image,p); Da=QuantumScale*GetPixelAlpha(reconstruct_image,q); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double pixel; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; if (channel == AlphaPixelChannel) pixel=(double) p[i]-GetPixelChannel(reconstruct_image,channel,q); else pixel=Sa*p[i]-Da*GetPixelChannel(reconstruct_image,channel,q); distance+=pixel*pixel; if (distance >= fuzz) { channel_distortion[i]++; difference=MagickTrue; } } if (difference != MagickFalse) channel_distortion[CompositePixelChannel]++; p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_GetAbsoluteDistortion) #endif for (j=0; j <= MaxPixelChannels; j++) distortion[j]+=channel_distortion[j]; } reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); return(status); } static MagickBooleanType GetFuzzDistortion(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { CacheView *image_view, *reconstruct_view; double area; MagickBooleanType status; register ssize_t j; size_t columns, rows; ssize_t y; status=MagickTrue; rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); area=0.0; image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(status) \ magick_number_threads(image,image,rows,1) reduction(+:area) #endif for (y=0; y < (ssize_t) rows; y++) { double channel_distortion[MaxPixelChannels+1]; register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) { status=MagickFalse; continue; } (void) memset(channel_distortion,0,sizeof(channel_distortion)); for (x=0; x < (ssize_t) columns; x++) { double Da, Sa; register ssize_t i; if ((GetPixelReadMask(image,p) <= (QuantumRange/2)) || (GetPixelReadMask(reconstruct_image,q) <= (QuantumRange/2))) { p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); continue; } Sa=QuantumScale*GetPixelAlpha(image,p); Da=QuantumScale*GetPixelAlpha(reconstruct_image,q); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double distance; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; if (channel == AlphaPixelChannel) distance=QuantumScale*(p[i]-GetPixelChannel(reconstruct_image, channel,q)); else distance=QuantumScale*(Sa*p[i]-Da*GetPixelChannel(reconstruct_image, channel,q)); channel_distortion[i]+=distance*distance; channel_distortion[CompositePixelChannel]+=distance*distance; } area++; p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_GetFuzzDistortion) #endif for (j=0; j <= MaxPixelChannels; j++) distortion[j]+=channel_distortion[j]; } reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); area=PerceptibleReciprocal(area); for (j=0; j <= MaxPixelChannels; j++) distortion[j]*=area; distortion[CompositePixelChannel]/=(double) GetImageChannels(image); distortion[CompositePixelChannel]=sqrt(distortion[CompositePixelChannel]); return(status); } static MagickBooleanType GetMeanAbsoluteDistortion(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { CacheView *image_view, *reconstruct_view; double area; MagickBooleanType status; register ssize_t j; size_t columns, rows; ssize_t y; status=MagickTrue; rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); area=0.0; image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(status) \ magick_number_threads(image,image,rows,1) reduction(+:area) #endif for (y=0; y < (ssize_t) rows; y++) { double channel_distortion[MaxPixelChannels+1]; register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL)) { status=MagickFalse; continue; } (void) memset(channel_distortion,0,sizeof(channel_distortion)); for (x=0; x < (ssize_t) columns; x++) { double Da, Sa; register ssize_t i; if ((GetPixelReadMask(image,p) <= (QuantumRange/2)) || (GetPixelReadMask(reconstruct_image,q) <= (QuantumRange/2))) { p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); continue; } Sa=QuantumScale*GetPixelAlpha(image,p); Da=QuantumScale*GetPixelAlpha(reconstruct_image,q); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double distance; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; if (channel == AlphaPixelChannel) distance=QuantumScale*fabs((double) p[i]- GetPixelChannel(reconstruct_image,channel,q)); else distance=QuantumScale*fabs(Sa*p[i]-Da* GetPixelChannel(reconstruct_image,channel,q)); channel_distortion[i]+=distance; channel_distortion[CompositePixelChannel]+=distance; } area++; p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_GetMeanAbsoluteError) #endif for (j=0; j <= MaxPixelChannels; j++) distortion[j]+=channel_distortion[j]; } reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); area=PerceptibleReciprocal(area); for (j=0; j <= MaxPixelChannels; j++) distortion[j]*=area; distortion[CompositePixelChannel]/=(double) GetImageChannels(image); return(status); } static MagickBooleanType GetMeanErrorPerPixel(Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { CacheView *image_view, *reconstruct_view; MagickBooleanType status; double area, maximum_error, mean_error; size_t columns, rows; ssize_t y; status=MagickTrue; area=0.0; maximum_error=0.0; mean_error=0.0; rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); for (y=0; y < (ssize_t) rows; y++) { register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t x; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL)) { status=MagickFalse; break; } for (x=0; x < (ssize_t) columns; x++) { double Da, Sa; register ssize_t i; if ((GetPixelReadMask(image,p) <= (QuantumRange/2)) || (GetPixelReadMask(reconstruct_image,q) <= (QuantumRange/2))) { p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); continue; } Sa=QuantumScale*GetPixelAlpha(image,p); Da=QuantumScale*GetPixelAlpha(reconstruct_image,q); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double distance; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; if (channel == AlphaPixelChannel) distance=fabs((double) p[i]- GetPixelChannel(reconstruct_image,channel,q)); else distance=fabs(Sa*p[i]-Da* GetPixelChannel(reconstruct_image,channel,q)); distortion[i]+=distance; distortion[CompositePixelChannel]+=distance; mean_error+=distance*distance; if (distance > maximum_error) maximum_error=distance; area++; } p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } } reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); image->error.mean_error_per_pixel=distortion[CompositePixelChannel]/area; image->error.normalized_mean_error=QuantumScale*QuantumScale*mean_error/area; image->error.normalized_maximum_error=QuantumScale*maximum_error; return(status); } static MagickBooleanType GetMeanSquaredDistortion(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { CacheView *image_view, *reconstruct_view; double area; MagickBooleanType status; register ssize_t j; size_t columns, rows; ssize_t y; status=MagickTrue; rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); area=0.0; image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(status) \ magick_number_threads(image,image,rows,1) reduction(+:area) #endif for (y=0; y < (ssize_t) rows; y++) { double channel_distortion[MaxPixelChannels+1]; register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL)) { status=MagickFalse; continue; } (void) memset(channel_distortion,0,sizeof(channel_distortion)); for (x=0; x < (ssize_t) columns; x++) { double Da, Sa; register ssize_t i; if ((GetPixelReadMask(image,p) <= (QuantumRange/2)) || (GetPixelReadMask(reconstruct_image,q) <= (QuantumRange/2))) { p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); continue; } Sa=QuantumScale*GetPixelAlpha(image,p); Da=QuantumScale*GetPixelAlpha(reconstruct_image,q); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double distance; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; if (channel == AlphaPixelChannel) distance=QuantumScale*(p[i]-GetPixelChannel(reconstruct_image, channel,q)); else distance=QuantumScale*(Sa*p[i]-Da*GetPixelChannel(reconstruct_image, channel,q)); channel_distortion[i]+=distance*distance; channel_distortion[CompositePixelChannel]+=distance*distance; } area++; p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_GetMeanSquaredError) #endif for (j=0; j <= MaxPixelChannels; j++) distortion[j]+=channel_distortion[j]; } reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); area=PerceptibleReciprocal(area); for (j=0; j <= MaxPixelChannels; j++) distortion[j]*=area; distortion[CompositePixelChannel]/=GetImageChannels(image); return(status); } static MagickBooleanType GetNormalizedCrossCorrelationDistortion( const Image *image,const Image *reconstruct_image,double *distortion, ExceptionInfo *exception) { #define SimilarityImageTag "Similarity/Image" CacheView *image_view, *reconstruct_view; ChannelStatistics *image_statistics, *reconstruct_statistics; double area; MagickBooleanType status; MagickOffsetType progress; register ssize_t i; size_t columns, rows; ssize_t y; /* Normalize to account for variation due to lighting and exposure condition. */ image_statistics=GetImageStatistics(image,exception); reconstruct_statistics=GetImageStatistics(reconstruct_image,exception); if ((image_statistics == (ChannelStatistics *) NULL) || (reconstruct_statistics == (ChannelStatistics *) NULL)) { if (image_statistics != (ChannelStatistics *) NULL) image_statistics=(ChannelStatistics *) RelinquishMagickMemory( image_statistics); if (reconstruct_statistics != (ChannelStatistics *) NULL) reconstruct_statistics=(ChannelStatistics *) RelinquishMagickMemory( reconstruct_statistics); return(MagickFalse); } status=MagickTrue; progress=0; for (i=0; i <= MaxPixelChannels; i++) distortion[i]=0.0; rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); area=0.0; image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); for (y=0; y < (ssize_t) rows; y++) { register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t x; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL)) { status=MagickFalse; break; } for (x=0; x < (ssize_t) columns; x++) { if ((GetPixelReadMask(image,p) <= (QuantumRange/2)) || (GetPixelReadMask(reconstruct_image,q) <= (QuantumRange/2))) { p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); continue; } area++; p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } } area=PerceptibleReciprocal(area); for (y=0; y < (ssize_t) rows; y++) { register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t x; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL)) { status=MagickFalse; break; } for (x=0; x < (ssize_t) columns; x++) { double Da, Sa; if ((GetPixelReadMask(image,p) <= (QuantumRange/2)) || (GetPixelReadMask(reconstruct_image,q) <= (QuantumRange/2))) { p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); continue; } Sa=QuantumScale*GetPixelAlpha(image,p); Da=QuantumScale*GetPixelAlpha(reconstruct_image,q); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; if (channel == AlphaPixelChannel) { distortion[i]+=area*QuantumScale*(p[i]- image_statistics[channel].mean)*(GetPixelChannel( reconstruct_image,channel,q)- reconstruct_statistics[channel].mean); } else { distortion[i]+=area*QuantumScale*(Sa*p[i]- image_statistics[channel].mean)*(Da*GetPixelChannel( reconstruct_image,channel,q)- reconstruct_statistics[channel].mean); } } p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp atomic #endif progress++; proceed=SetImageProgress(image,SimilarityImageTag,progress,rows); if (proceed == MagickFalse) { status=MagickFalse; break; } } } reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); /* Divide by the standard deviation. */ distortion[CompositePixelChannel]=0.0; for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double gamma; PixelChannel channel = GetPixelChannelChannel(image,i); gamma=image_statistics[channel].standard_deviation* reconstruct_statistics[channel].standard_deviation; gamma=PerceptibleReciprocal(gamma); distortion[i]=QuantumRange*gamma*distortion[i]; distortion[CompositePixelChannel]+=distortion[i]*distortion[i]; } distortion[CompositePixelChannel]=sqrt(distortion[CompositePixelChannel]/ GetImageChannels(image)); /* Free resources. */ reconstruct_statistics=(ChannelStatistics *) RelinquishMagickMemory( reconstruct_statistics); image_statistics=(ChannelStatistics *) RelinquishMagickMemory( image_statistics); return(status); } static MagickBooleanType GetPeakAbsoluteDistortion(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { CacheView *image_view, *reconstruct_view; MagickBooleanType status; size_t columns, rows; ssize_t y; status=MagickTrue; rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(status) \ magick_number_threads(image,image,rows,1) #endif for (y=0; y < (ssize_t) rows; y++) { double channel_distortion[MaxPixelChannels+1]; register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t j, x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL)) { status=MagickFalse; continue; } (void) memset(channel_distortion,0,sizeof(channel_distortion)); for (x=0; x < (ssize_t) columns; x++) { double Da, Sa; register ssize_t i; if ((GetPixelReadMask(image,p) <= (QuantumRange/2)) || (GetPixelReadMask(reconstruct_image,q) <= (QuantumRange/2))) { p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); continue; } Sa=QuantumScale*GetPixelAlpha(image,p); Da=QuantumScale*GetPixelAlpha(reconstruct_image,q); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double distance; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; if (channel == AlphaPixelChannel) distance=QuantumScale*fabs((double) p[i]- GetPixelChannel(reconstruct_image,channel,q)); else distance=QuantumScale*fabs(Sa*p[i]-Da* GetPixelChannel(reconstruct_image,channel,q)); if (distance > channel_distortion[i]) channel_distortion[i]=distance; if (distance > channel_distortion[CompositePixelChannel]) channel_distortion[CompositePixelChannel]=distance; } p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_GetPeakAbsoluteError) #endif for (j=0; j <= MaxPixelChannels; j++) if (channel_distortion[j] > distortion[j]) distortion[j]=channel_distortion[j]; } reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); return(status); } static inline double MagickLog10(const double x) { #define Log10Epsilon (1.0e-11) if (fabs(x) < Log10Epsilon) return(log10(Log10Epsilon)); return(log10(fabs(x))); } static MagickBooleanType GetPeakSignalToNoiseRatio(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { MagickBooleanType status; register ssize_t i; status=GetMeanSquaredDistortion(image,reconstruct_image,distortion,exception); for (i=0; i <= MaxPixelChannels; i++) if (fabs(distortion[i]) < MagickEpsilon) distortion[i]=INFINITY; else distortion[i]=10.0*MagickLog10(1.0)-10.0*MagickLog10(distortion[i]); return(status); } static MagickBooleanType GetPerceptualHashDistortion(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { ChannelPerceptualHash *channel_phash, *reconstruct_phash; const char *artifact; MagickBooleanType normalize; ssize_t channel; /* Compute perceptual hash in the sRGB colorspace. */ channel_phash=GetImagePerceptualHash(image,exception); if (channel_phash == (ChannelPerceptualHash *) NULL) return(MagickFalse); reconstruct_phash=GetImagePerceptualHash(reconstruct_image,exception); if (reconstruct_phash == (ChannelPerceptualHash *) NULL) { channel_phash=(ChannelPerceptualHash *) RelinquishMagickMemory( channel_phash); return(MagickFalse); } artifact=GetImageArtifact(image,"phash:normalize"); normalize=(artifact == (const char *) NULL) || (IsStringTrue(artifact) == MagickFalse) ? MagickFalse : MagickTrue; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) #endif for (channel=0; channel < MaxPixelChannels; channel++) { double difference; register ssize_t i; difference=0.0; for (i=0; i < MaximumNumberOfImageMoments; i++) { double alpha, beta; register ssize_t j; for (j=0; j < (ssize_t) channel_phash[0].number_colorspaces; j++) { alpha=channel_phash[channel].phash[j][i]; beta=reconstruct_phash[channel].phash[j][i]; if (normalize == MagickFalse) difference+=(beta-alpha)*(beta-alpha); else difference=sqrt((beta-alpha)*(beta-alpha)/ channel_phash[0].number_channels); } } distortion[channel]+=difference; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_GetPerceptualHashDistortion) #endif distortion[CompositePixelChannel]+=difference; } /* Free resources. */ reconstruct_phash=(ChannelPerceptualHash *) RelinquishMagickMemory( reconstruct_phash); channel_phash=(ChannelPerceptualHash *) RelinquishMagickMemory(channel_phash); return(MagickTrue); } static MagickBooleanType GetRootMeanSquaredDistortion(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { MagickBooleanType status; register ssize_t i; status=GetMeanSquaredDistortion(image,reconstruct_image,distortion,exception); for (i=0; i <= MaxPixelChannels; i++) distortion[i]=sqrt(distortion[i]); return(status); } static MagickBooleanType GetStructuralSimilarityDistortion(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { #define SSIMRadius 5.0 #define SSIMSigma 1.5 #define SSIMBlocksize 8 #define SSIMK1 0.01 #define SSIMK2 0.03 #define SSIML 1.0 CacheView *image_view, *reconstruct_view; char geometry[MagickPathExtent]; const char *artifact; double c1, c2, radius, sigma; KernelInfo *kernel_info; MagickBooleanType status; register ssize_t i; size_t columns, rows; ssize_t y; /* Compute structural similarity index @ https://en.wikipedia.org/wiki/Structural_similarity. */ radius=SSIMRadius; artifact=GetImageArtifact(image,"compare:ssim-radius"); if (artifact != (const char *) NULL) radius=StringToDouble(artifact,(char **) NULL); sigma=SSIMSigma; artifact=GetImageArtifact(image,"compare:ssim-sigma"); if (artifact != (const char *) NULL) sigma=StringToDouble(artifact,(char **) NULL); (void) FormatLocaleString(geometry,MagickPathExtent,"gaussian:%.20gx%.20g", radius,sigma); kernel_info=AcquireKernelInfo(geometry,exception); if (kernel_info == (KernelInfo *) NULL) ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", image->filename); c1=pow(SSIMK1*SSIML,2.0); artifact=GetImageArtifact(image,"compare:ssim-k1"); if (artifact != (const char *) NULL) c1=pow(StringToDouble(artifact,(char **) NULL)*SSIML,2.0); c2=pow(SSIMK2*SSIML,2.0); artifact=GetImageArtifact(image,"compare:ssim-k2"); if (artifact != (const char *) NULL) c2=pow(StringToDouble(artifact,(char **) NULL)*SSIML,2.0); status=MagickTrue; rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(status) \ magick_number_threads(image,reconstruct_image,rows,1) #endif for (y=0; y < (ssize_t) rows; y++) { double channel_distortion[MaxPixelChannels+1]; register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t i, x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,-((ssize_t) kernel_info->width/2L),y- ((ssize_t) kernel_info->height/2L),columns+kernel_info->width, kernel_info->height,exception); q=GetCacheViewVirtualPixels(reconstruct_view,-((ssize_t) kernel_info->width/ 2L),y-((ssize_t) kernel_info->height/2L),columns+kernel_info->width, kernel_info->height,exception); if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL)) { status=MagickFalse; continue; } (void) memset(channel_distortion,0,sizeof(channel_distortion)); for (x=0; x < (ssize_t) columns; x++) { double x_pixel_mu[MaxPixelChannels+1], x_pixel_sigma_squared[MaxPixelChannels+1], xy_sigma[MaxPixelChannels+1], y_pixel_mu[MaxPixelChannels+1], y_pixel_sigma_squared[MaxPixelChannels+1]; register const Quantum *magick_restrict reference, *magick_restrict target; register MagickRealType *k; ssize_t v; (void) memset(x_pixel_mu,0,sizeof(x_pixel_mu)); (void) memset(x_pixel_sigma_squared,0,sizeof(x_pixel_sigma_squared)); (void) memset(xy_sigma,0,sizeof(xy_sigma)); (void) memset(x_pixel_sigma_squared,0,sizeof(y_pixel_sigma_squared)); (void) memset(y_pixel_mu,0,sizeof(y_pixel_mu)); (void) memset(y_pixel_sigma_squared,0,sizeof(y_pixel_sigma_squared)); k=kernel_info->values; reference=p; target=q; for (v=0; v < (ssize_t) kernel_info->height; v++) { register ssize_t u; for (u=0; u < (ssize_t) kernel_info->width; u++) { for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double x_pixel, y_pixel; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits( reconstruct_image,channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; x_pixel=QuantumScale*reference[i]; x_pixel_mu[i]+=(*k)*x_pixel; x_pixel_sigma_squared[i]+=(*k)*x_pixel*x_pixel; y_pixel=QuantumScale* GetPixelChannel(reconstruct_image,channel,target); y_pixel_mu[i]+=(*k)*y_pixel; y_pixel_sigma_squared[i]+=(*k)*y_pixel*y_pixel; xy_sigma[i]+=(*k)*x_pixel*y_pixel; } k++; reference+=GetPixelChannels(image); target+=GetPixelChannels(reconstruct_image); } reference+=GetPixelChannels(image)*columns; target+=GetPixelChannels(reconstruct_image)*columns; } for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double ssim, x_pixel_mu_squared, x_pixel_sigmas_squared, xy_mu, xy_sigmas, y_pixel_mu_squared, y_pixel_sigmas_squared; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits( reconstruct_image,channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; x_pixel_mu_squared=x_pixel_mu[i]*x_pixel_mu[i]; y_pixel_mu_squared=y_pixel_mu[i]*y_pixel_mu[i]; xy_mu=x_pixel_mu[i]*y_pixel_mu[i]; xy_sigmas=xy_sigma[i]-xy_mu; x_pixel_sigmas_squared=x_pixel_sigma_squared[i]-x_pixel_mu_squared; y_pixel_sigmas_squared=y_pixel_sigma_squared[i]-y_pixel_mu_squared; ssim=((2.0*xy_mu+c1)*(2.0*xy_sigmas+c2))/ ((x_pixel_mu_squared+y_pixel_mu_squared+c1)* (x_pixel_sigmas_squared+y_pixel_sigmas_squared+c2)); channel_distortion[i]+=ssim; channel_distortion[CompositePixelChannel]+=ssim; } p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_GetStructuralSimilarityDistortion) #endif for (i=0; i <= MaxPixelChannels; i++) distortion[i]+=channel_distortion[i]; } image_view=DestroyCacheView(image_view); reconstruct_view=DestroyCacheView(reconstruct_view); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits == UndefinedPixelTrait) || ((traits & UpdatePixelTrait) == 0)) continue; distortion[i]/=((double) columns*rows); } distortion[CompositePixelChannel]/=((double) columns*rows); distortion[CompositePixelChannel]/=(double) GetImageChannels(image); kernel_info=DestroyKernelInfo(kernel_info); return(status); } static MagickBooleanType GetStructuralDisimilarityDistortion(const Image *image, const Image *reconstruct_image,double *distortion,ExceptionInfo *exception) { MagickBooleanType status; register ssize_t i; status=GetStructuralSimilarityDistortion(image,reconstruct_image, distortion,exception); for (i=0; i <= MaxPixelChannels; i++) distortion[i]=(1.0-(distortion[i]))/2.0; return(status); } MagickExport MagickBooleanType GetImageDistortion(Image *image, const Image *reconstruct_image,const MetricType metric,double *distortion, ExceptionInfo *exception) { double *channel_distortion; MagickBooleanType status; size_t length; assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(reconstruct_image != (const Image *) NULL); assert(reconstruct_image->signature == MagickCoreSignature); assert(distortion != (double *) NULL); *distortion=0.0; if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); /* Get image distortion. */ length=MaxPixelChannels+1; channel_distortion=(double *) AcquireQuantumMemory(length, sizeof(*channel_distortion)); if (channel_distortion == (double *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) memset(channel_distortion,0,length* sizeof(*channel_distortion)); switch (metric) { case AbsoluteErrorMetric: { status=GetAbsoluteDistortion(image,reconstruct_image,channel_distortion, exception); break; } case FuzzErrorMetric: { status=GetFuzzDistortion(image,reconstruct_image,channel_distortion, exception); break; } case MeanAbsoluteErrorMetric: { status=GetMeanAbsoluteDistortion(image,reconstruct_image, channel_distortion,exception); break; } case MeanErrorPerPixelErrorMetric: { status=GetMeanErrorPerPixel(image,reconstruct_image,channel_distortion, exception); break; } case MeanSquaredErrorMetric: { status=GetMeanSquaredDistortion(image,reconstruct_image, channel_distortion,exception); break; } case NormalizedCrossCorrelationErrorMetric: default: { status=GetNormalizedCrossCorrelationDistortion(image,reconstruct_image, channel_distortion,exception); break; } case PeakAbsoluteErrorMetric: { status=GetPeakAbsoluteDistortion(image,reconstruct_image, channel_distortion,exception); break; } case PeakSignalToNoiseRatioErrorMetric: { status=GetPeakSignalToNoiseRatio(image,reconstruct_image, channel_distortion,exception); break; } case PerceptualHashErrorMetric: { status=GetPerceptualHashDistortion(image,reconstruct_image, channel_distortion,exception); break; } case RootMeanSquaredErrorMetric: { status=GetRootMeanSquaredDistortion(image,reconstruct_image, channel_distortion,exception); break; } case StructuralSimilarityErrorMetric: { status=GetStructuralSimilarityDistortion(image,reconstruct_image, channel_distortion,exception); break; } case StructuralDissimilarityErrorMetric: { status=GetStructuralDisimilarityDistortion(image,reconstruct_image, channel_distortion,exception); break; } } *distortion=channel_distortion[CompositePixelChannel]; channel_distortion=(double *) RelinquishMagickMemory(channel_distortion); (void) FormatImageProperty(image,"distortion","%.*g",GetMagickPrecision(), *distortion); return(status); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t I m a g e D i s t o r t i o n s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetImageDistortions() compares the pixel channels of an image to a % reconstructed image and returns the specified distortion metric for each % channel. % % The format of the GetImageDistortions method is: % % double *GetImageDistortions(const Image *image, % const Image *reconstruct_image,const MetricType metric, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the image. % % o reconstruct_image: the reconstruct image. % % o metric: the metric. % % o exception: return any errors or warnings in this structure. % */ MagickExport double *GetImageDistortions(Image *image, const Image *reconstruct_image,const MetricType metric, ExceptionInfo *exception) { double *channel_distortion; MagickBooleanType status; size_t length; assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(reconstruct_image != (const Image *) NULL); assert(reconstruct_image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); /* Get image distortion. */ length=MaxPixelChannels+1UL; channel_distortion=(double *) AcquireQuantumMemory(length, sizeof(*channel_distortion)); if (channel_distortion == (double *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) memset(channel_distortion,0,length* sizeof(*channel_distortion)); status=MagickTrue; switch (metric) { case AbsoluteErrorMetric: { status=GetAbsoluteDistortion(image,reconstruct_image,channel_distortion, exception); break; } case FuzzErrorMetric: { status=GetFuzzDistortion(image,reconstruct_image,channel_distortion, exception); break; } case MeanAbsoluteErrorMetric: { status=GetMeanAbsoluteDistortion(image,reconstruct_image, channel_distortion,exception); break; } case MeanErrorPerPixelErrorMetric: { status=GetMeanErrorPerPixel(image,reconstruct_image,channel_distortion, exception); break; } case MeanSquaredErrorMetric: { status=GetMeanSquaredDistortion(image,reconstruct_image, channel_distortion,exception); break; } case NormalizedCrossCorrelationErrorMetric: default: { status=GetNormalizedCrossCorrelationDistortion(image,reconstruct_image, channel_distortion,exception); break; } case PeakAbsoluteErrorMetric: { status=GetPeakAbsoluteDistortion(image,reconstruct_image, channel_distortion,exception); break; } case PeakSignalToNoiseRatioErrorMetric: { status=GetPeakSignalToNoiseRatio(image,reconstruct_image, channel_distortion,exception); break; } case PerceptualHashErrorMetric: { status=GetRootMeanSquaredDistortion(image,reconstruct_image, channel_distortion,exception); break; } case RootMeanSquaredErrorMetric: { status=GetRootMeanSquaredDistortion(image,reconstruct_image, channel_distortion,exception); break; } case StructuralSimilarityErrorMetric: { status=GetStructuralSimilarityDistortion(image,reconstruct_image, channel_distortion,exception); break; } case StructuralDissimilarityErrorMetric: { status=GetStructuralDisimilarityDistortion(image,reconstruct_image, channel_distortion,exception); break; } } if (status == MagickFalse) { channel_distortion=(double *) RelinquishMagickMemory(channel_distortion); return((double *) NULL); } return(channel_distortion); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % I s I m a g e s E q u a l % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % IsImagesEqual() compare the pixels of two images and returns immediately % if any pixel is not identical. % % The format of the IsImagesEqual method is: % % MagickBooleanType IsImagesEqual(const Image *image, % const Image *reconstruct_image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image: the image. % % o reconstruct_image: the reconstruct image. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType IsImagesEqual(const Image *image, const Image *reconstruct_image,ExceptionInfo *exception) { CacheView *image_view, *reconstruct_view; size_t columns, rows; ssize_t y; assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); assert(reconstruct_image != (const Image *) NULL); assert(reconstruct_image->signature == MagickCoreSignature); rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); for (y=0; y < (ssize_t) rows; y++) { register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t x; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) break; for (x=0; x < (ssize_t) columns; x++) { register ssize_t i; for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double distance; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; distance=fabs(p[i]-(double) GetPixelChannel(reconstruct_image, channel,q)); if (distance >= MagickEpsilon) break; } if (i < (ssize_t) GetPixelChannels(image)) break; p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } if (x < (ssize_t) columns) break; } reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); return(y < (ssize_t) rows ? MagickFalse : MagickTrue); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % S e t I m a g e C o l o r M e t r i c % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SetImageColorMetric() measures the difference between colors at each pixel % location of two images. A value other than 0 means the colors match % exactly. Otherwise an error measure is computed by summing over all % pixels in an image the distance squared in RGB space between each image % pixel and its corresponding pixel in the reconstruct image. The error % measure is assigned to these image members: % % o mean_error_per_pixel: The mean error for any single pixel in % the image. % % o normalized_mean_error: The normalized mean quantization error for % any single pixel in the image. This distance measure is normalized to % a range between 0 and 1. It is independent of the range of red, green, % and blue values in the image. % % o normalized_maximum_error: The normalized maximum quantization % error for any single pixel in the image. This distance measure is % normalized to a range between 0 and 1. It is independent of the range % of red, green, and blue values in your image. % % A small normalized mean square error, accessed as % image->normalized_mean_error, suggests the images are very similar in % spatial layout and color. % % The format of the SetImageColorMetric method is: % % MagickBooleanType SetImageColorMetric(Image *image, % const Image *reconstruct_image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image: the image. % % o reconstruct_image: the reconstruct image. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType SetImageColorMetric(Image *image, const Image *reconstruct_image,ExceptionInfo *exception) { CacheView *image_view, *reconstruct_view; double area, maximum_error, mean_error, mean_error_per_pixel; MagickBooleanType status; size_t columns, rows; ssize_t y; assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); assert(reconstruct_image != (const Image *) NULL); assert(reconstruct_image->signature == MagickCoreSignature); area=0.0; maximum_error=0.0; mean_error_per_pixel=0.0; mean_error=0.0; rows=MagickMax(image->rows,reconstruct_image->rows); columns=MagickMax(image->columns,reconstruct_image->columns); image_view=AcquireVirtualCacheView(image,exception); reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); for (y=0; y < (ssize_t) rows; y++) { register const Quantum *magick_restrict p, *magick_restrict q; register ssize_t x; p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) break; for (x=0; x < (ssize_t) columns; x++) { register ssize_t i; for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { double distance; PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait reconstruct_traits = GetPixelChannelTraits(reconstruct_image, channel); if ((traits == UndefinedPixelTrait) || (reconstruct_traits == UndefinedPixelTrait) || ((reconstruct_traits & UpdatePixelTrait) == 0)) continue; distance=fabs(p[i]-(double) GetPixelChannel(reconstruct_image, channel,q)); if (distance >= MagickEpsilon) { mean_error_per_pixel+=distance; mean_error+=distance*distance; if (distance > maximum_error) maximum_error=distance; } area++; } p+=GetPixelChannels(image); q+=GetPixelChannels(reconstruct_image); } } reconstruct_view=DestroyCacheView(reconstruct_view); image_view=DestroyCacheView(image_view); image->error.mean_error_per_pixel=(double) (mean_error_per_pixel/area); image->error.normalized_mean_error=(double) (QuantumScale*QuantumScale* mean_error/area); image->error.normalized_maximum_error=(double) (QuantumScale*maximum_error); status=image->error.mean_error_per_pixel == 0.0 ? MagickTrue : MagickFalse; return(status); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % S i m i l a r i t y I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SimilarityImage() compares the reference image of the image and returns the % best match offset. In addition, it returns a similarity image such that an % exact match location is completely white and if none of the pixels match, % black, otherwise some gray level in-between. % % The format of the SimilarityImageImage method is: % % Image *SimilarityImage(const Image *image,const Image *reference, % const MetricType metric,const double similarity_threshold, % RectangleInfo *offset,double *similarity,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the image. % % o reference: find an area of the image that closely resembles this image. % % o metric: the metric. % % o similarity_threshold: minimum distortion for (sub)image match. % % o offset: the best match offset of the reference image within the image. % % o similarity: the computed similarity between the images. % % o exception: return any errors or warnings in this structure. % */ static double GetSimilarityMetric(const Image *image,const Image *reference, const MetricType metric,const ssize_t x_offset,const ssize_t y_offset, ExceptionInfo *exception) { double distortion; Image *similarity_image; MagickBooleanType status; RectangleInfo geometry; SetGeometry(reference,&geometry); geometry.x=x_offset; geometry.y=y_offset; similarity_image=CropImage(image,&geometry,exception); if (similarity_image == (Image *) NULL) return(0.0); distortion=0.0; status=GetImageDistortion(similarity_image,reference,metric,&distortion, exception); similarity_image=DestroyImage(similarity_image); if (status == MagickFalse) return(0.0); return(distortion); } MagickExport Image *SimilarityImage(const Image *image,const Image *reference, const MetricType metric,const double similarity_threshold, RectangleInfo *offset,double *similarity_metric,ExceptionInfo *exception) { #define SimilarityImageTag "Similarity/Image" CacheView *similarity_view; Image *similarity_image; MagickBooleanType status; MagickOffsetType progress; ssize_t y; assert(image != (const Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); assert(offset != (RectangleInfo *) NULL); SetGeometry(reference,offset); *similarity_metric=MagickMaximumValue; similarity_image=CloneImage(image,image->columns-reference->columns+1, image->rows-reference->rows+1,MagickTrue,exception); if (similarity_image == (Image *) NULL) return((Image *) NULL); status=SetImageStorageClass(similarity_image,DirectClass,exception); if (status == MagickFalse) { similarity_image=DestroyImage(similarity_image); return((Image *) NULL); } (void) SetImageAlphaChannel(similarity_image,DeactivateAlphaChannel, exception); /* Measure similarity of reference image against image. */ status=MagickTrue; progress=0; similarity_view=AcquireAuthenticCacheView(similarity_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) \ shared(progress,status,similarity_metric) \ magick_number_threads(image,image,image->rows-reference->rows+1,1) #endif for (y=0; y < (ssize_t) (image->rows-reference->rows+1); y++) { double similarity; register Quantum *magick_restrict q; register ssize_t x; if (status == MagickFalse) continue; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp flush(similarity_metric) #endif if (*similarity_metric <= similarity_threshold) continue; q=GetCacheViewAuthenticPixels(similarity_view,0,y,similarity_image->columns, 1,exception); if (q == (Quantum *) NULL) { status=MagickFalse; continue; } for (x=0; x < (ssize_t) (image->columns-reference->columns+1); x++) { register ssize_t i; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp flush(similarity_metric) #endif if (*similarity_metric <= similarity_threshold) break; similarity=GetSimilarityMetric(image,reference,metric,x,y,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_SimilarityImage) #endif if ((metric == NormalizedCrossCorrelationErrorMetric) || (metric == UndefinedErrorMetric)) similarity=1.0-similarity; if (similarity < *similarity_metric) { offset->x=x; offset->y=y; *similarity_metric=similarity; } if (metric == PerceptualHashErrorMetric) similarity=MagickMin(0.01*similarity,1.0); for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); PixelTrait similarity_traits=GetPixelChannelTraits(similarity_image, channel); if ((traits == UndefinedPixelTrait) || (similarity_traits == UndefinedPixelTrait) || ((similarity_traits & UpdatePixelTrait) == 0)) continue; SetPixelChannel(similarity_image,channel,ClampToQuantum(QuantumRange- QuantumRange*similarity),q); } q+=GetPixelChannels(similarity_image); } if (SyncCacheViewAuthenticPixels(similarity_view,exception) == MagickFalse) status=MagickFalse; if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp atomic #endif progress++; proceed=SetImageProgress(image,SimilarityImageTag,progress,image->rows); if (proceed == MagickFalse) status=MagickFalse; } } similarity_view=DestroyCacheView(similarity_view); if (status == MagickFalse) similarity_image=DestroyImage(similarity_image); return(similarity_image); }
Close