annotate src/similar.c @ 1672:994169573393

Complete commit @1747 (intltool usage) With using intltool the localisation will fail cause of missing desktop.in file. Also the old desktop files are obsoleted by this commit. Also it is not necessary any more to have a './' in front of the files in POTFILES.in.
author mow
date Sat, 27 Jun 2009 22:57:56 +0000
parents a6f9ba6fd751
children 956aab097ea7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
1 /*
196
f6e307c7bad6 rename GQview -> Geeqie over the code
nadvornik
parents: 9
diff changeset
2 * Geeqie
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
3 * (C) 2004 John Ellis
1284
8b89e3ff286b Add year 2009 to copyright info everywhere.
zas_
parents: 1055
diff changeset
4 * Copyright (C) 2008 - 2009 The Geeqie Team
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
5 *
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
6 * Author: John Ellis
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
7 *
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
8 * This software is released under the GNU General Public License (GNU GPL).
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
9 * Please read the included file COPYING for more information.
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
10 * This software comes with no warranty of any kind, use at your own risk!
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
11 */
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
12
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
13
281
9995c5fb202a gqview.h -> main.h
zas_
parents: 196
diff changeset
14 #include "main.h"
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
15 #include "similar.h"
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
16
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
17 /*
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
18 * These functions are intended to find images with similar color content. For
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
19 * example when an image was saved at different compression levels or dimensions
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
20 * (scaled down/up) the contents are similar, but these files do not match by file
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
21 * size, dimensions, or checksum.
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
22 *
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
23 * These functions create a 32 x 32 array for each color channel (red, green, blue).
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
24 * The array represents the average color of each corresponding part of the
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
25 * image. (imagine the image cut into 1024 rectangles, or a 32 x 32 grid.
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
26 * Each grid is then processed for the average color value, this is what
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
27 * is stored in the array)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
28 *
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
29 * To compare two images, generate a ImageSimilarityData for each image, then
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
30 * pass them to the compare function. The return value is the percent match
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
31 * of the two images. (for this, simple comparisons are used, basically the return
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
32 * is an average of the corresponding array differences)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
33 *
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
34 * for image_sim_compare(), the return is 0.0 to 1.0:
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
35 * 1.0 for exact matches (an image is compared to itself)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
36 * 0.0 for exact opposite images (compare an all black to an all white image)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
37 * generally only a match of > 0.85 are significant at all, and >.95 is useful to
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
38 * find images that have been re-saved to other formats, dimensions, or compression.
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
39 */
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
40
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
41
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
42 /*
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
43 * The experimental (alternate) algorithm is only for testing of new techniques to
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
44 * improve the result, and hopes to reduce false positives.
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
45 */
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
46
1420
3a9fb1b52559 Use gboolean where applicable, for the sake of consistency.
zas_
parents: 1284
diff changeset
47 static gboolean alternate_enabled = FALSE;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
48
1420
3a9fb1b52559 Use gboolean where applicable, for the sake of consistency.
zas_
parents: 1284
diff changeset
49 void image_sim_alternate_set(gboolean enable)
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
50 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
51 alternate_enabled = enable;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
52 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
53
1420
3a9fb1b52559 Use gboolean where applicable, for the sake of consistency.
zas_
parents: 1284
diff changeset
54 gboolean image_sim_alternate_enabled(void)
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
55 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
56 return alternate_enabled;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
57 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
58
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
59 ImageSimilarityData *image_sim_new(void)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
60 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
61 ImageSimilarityData *sd = g_new0(ImageSimilarityData, 1);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
62
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
63 return sd;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
64 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
65
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
66 void image_sim_free(ImageSimilarityData *sd)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
67 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
68 g_free(sd);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
69 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
70
1003
4bfee4a63f86 const gpointer -> gconstpointer.
zas_
parents: 1002
diff changeset
71 static gint image_sim_channel_eq_sort_cb(gconstpointer a, gconstpointer b)
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
72 {
1002
3096a47232ec Use gpointer instead of void *.
zas_
parents: 1000
diff changeset
73 gint *pa = (gpointer)a;
3096a47232ec Use gpointer instead of void *.
zas_
parents: 1000
diff changeset
74 gint *pb = (gpointer)b;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
75 if (pa[1] < pb[1]) return -1;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
76 if (pa[1] > pb[1]) return 1;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
77 return 0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
78 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
79
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
80 static void image_sim_channel_equal(guint8 *pix, gint len)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
81 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
82 gint *buf;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
83 gint i;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
84 gint p;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
85
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
86 buf = g_new0(gint, len * 2);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
87
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
88 p = 0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
89 for (i = 0; i < len; i++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
90 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
91 buf[p] = i;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
92 p++;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
93 buf[p] = (gint)pix[i];
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
94 p++;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
95 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
96
512
f9bf33be53ff Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents: 475
diff changeset
97 qsort(buf, len, sizeof(gint) * 2, image_sim_channel_eq_sort_cb);
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
98
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
99 p = 0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
100 for (i = 0; i < len; i++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
101 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
102 gint n;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
103
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
104 n = buf[p];
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
105 p += 2;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
106 pix[n] = (guint8)(255 * i / len);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
107 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
108
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
109 g_free(buf);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
110 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
111
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
112 static void image_sim_channel_norm(guint8 *pix, gint len)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
113 {
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
114 guint8 l, h, delta;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
115 gint i;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
116 gdouble scale;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
117
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
118 l = h = pix[0];
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
119
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
120 for (i = 0; i < len; i++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
121 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
122 if (pix[i] < l) l = pix[i];
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
123 if (pix[i] > h) h = pix[i];
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
124 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
125
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
126 delta = h - l;
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
127 scale = (delta != 0) ? 255.0 / (gdouble)(delta) : 1.0;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
128
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
129 for (i = 0; i < len; i++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
130 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
131 pix[i] = (guint8)((gdouble)(pix[i] - l) * scale);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
132 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
133 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
134
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
135 /*
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
136 * define these to enable various components of the experimental compare functions
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
137 *
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
138 * Convert the thumbprint to greyscale (ignore all color information when comparing)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
139 * #define ALTERNATE_USES_GREYSCALE 1
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
140 *
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
141 * Take into account the difference in change from one pixel to the next
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
142 * #define ALTERNATE_INCLUDE_COMPARE_CHANGE 1
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
143 */
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
144
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
145 void image_sim_alternate_processing(ImageSimilarityData *sd)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
146 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
147 #ifdef ALTERNATE_USES_GREYSCALE
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
148 gint i;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
149 #endif
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
150
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
151 if (!alternate_enabled) return;
442
4b2d7f9af171 Big whitespaces cleanup:
zas_
parents: 281
diff changeset
152
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
153 image_sim_channel_norm(sd->avg_r, sizeof(sd->avg_r));
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
154 image_sim_channel_norm(sd->avg_g, sizeof(sd->avg_g));
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
155 image_sim_channel_norm(sd->avg_b, sizeof(sd->avg_b));
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
156
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
157 image_sim_channel_equal(sd->avg_r, sizeof(sd->avg_r));
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
158 image_sim_channel_equal(sd->avg_g, sizeof(sd->avg_g));
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
159 image_sim_channel_equal(sd->avg_b, sizeof(sd->avg_b));
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
160
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
161 #ifdef ALTERNATE_USES_GREYSCALE
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
162 for (i = 0; i < sizeof(sd->avg_r); i++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
163 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
164 guint8 n;
442
4b2d7f9af171 Big whitespaces cleanup:
zas_
parents: 281
diff changeset
165
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
166 n = (guint8)((gint)(sd->avg_r[i] + sd->avg_g[i] + sd->avg_b[i]) / 3);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
167 sd->avg_r[i] = sd->avg_g[i] = sd->avg_b[i] = n;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
168 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
169 #endif
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
170 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
171
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
172 void image_sim_fill_data(ImageSimilarityData *sd, GdkPixbuf *pixbuf)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
173 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
174 gint w, h;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
175 gint rs;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
176 guchar *pix;
1446
a6f9ba6fd751 gint -> gboolean.
zas_
parents: 1420
diff changeset
177 gboolean has_alpha;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
178 gint p_step;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
179
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
180 guchar *p;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
181 gint i;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
182 gint j;
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
183 gint x_inc, y_inc, xy_inc;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
184 gint xs, ys;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
185
1420
3a9fb1b52559 Use gboolean where applicable, for the sake of consistency.
zas_
parents: 1284
diff changeset
186 gboolean x_small = FALSE; /* if less than 32 w or h, set TRUE */
3a9fb1b52559 Use gboolean where applicable, for the sake of consistency.
zas_
parents: 1284
diff changeset
187 gboolean y_small = FALSE;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
188
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
189 if (!sd || !pixbuf) return;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
190
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
191 w = gdk_pixbuf_get_width(pixbuf);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
192 h = gdk_pixbuf_get_height(pixbuf);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
193 rs = gdk_pixbuf_get_rowstride(pixbuf);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
194 pix = gdk_pixbuf_get_pixels(pixbuf);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
195 has_alpha = gdk_pixbuf_get_has_alpha(pixbuf);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
196
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
197 p_step = has_alpha ? 4 : 3;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
198 x_inc = w / 32;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
199 y_inc = h / 32;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
200
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
201 if (x_inc < 1)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
202 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
203 x_inc = 1;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
204 x_small = TRUE;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
205 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
206 if (y_inc < 1)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
207 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
208 y_inc = 1;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
209 y_small = TRUE;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
210 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
211
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
212 xy_inc = x_inc * y_inc;
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
213
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
214 j = 0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
215
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
216 for (ys = 0; ys < 32; ys++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
217 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
218 if (y_small) j = (gdouble)h / 32 * ys;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
219
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
220 i = 0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
221
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
222 for (xs = 0; xs < 32; xs++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
223 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
224 gint x, y;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
225 gint r, g, b;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
226 gint t;
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
227 guchar *xpos;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
228
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
229 if (x_small) i = (gdouble)w / 32 * xs;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
230
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
231 r = g = b = 0;
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
232 xpos = pix + (i * p_step);
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
233
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
234 for (y = j; y < j + y_inc; y++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
235 {
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
236 p = xpos + (y * rs);
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
237 for (x = i; x < i + x_inc; x++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
238 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
239 r += *p; p++;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
240 g += *p; p++;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
241 b += *p; p++;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
242 if (has_alpha) p++;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
243 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
244 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
245
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
246 r /= xy_inc;
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
247 g /= xy_inc;
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
248 b /= xy_inc;
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
249
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
250 t = ys * 32 + xs;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
251 sd->avg_r[t] = r;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
252 sd->avg_g[t] = g;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
253 sd->avg_b[t] = b;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
254
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
255 i += x_inc;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
256 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
257
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
258 j += y_inc;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
259 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
260
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
261 sd->filled = TRUE;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
262 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
263
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
264 ImageSimilarityData *image_sim_new_from_pixbuf(GdkPixbuf *pixbuf)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
265 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
266 ImageSimilarityData *sd;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
267
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
268 sd = image_sim_new();
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
269 image_sim_fill_data(sd, pixbuf);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
270
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
271 return sd;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
272 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
273
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
274 #ifdef ALTERNATE_INCLUDE_COMPARE_CHANGE
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
275 static gdouble alternate_image_sim_compare_fast(ImageSimilarityData *a, ImageSimilarityData *b, gdouble min)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
276 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
277 gint sim;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
278 gint i;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
279 gint j;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
280 gint ld;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
281
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
282 if (!a || !b || !a->filled || !b->filled) return 0.0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
283
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
284 min = 1.0 - min;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
285 sim = 0.0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
286 ld = 0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
287
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
288 for (j = 0; j < 1024; j += 32)
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
289 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
290 for (i = j; i < j + 32; i++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
291 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
292 gint cr, cg, cb;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
293 gint cd;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
294
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
295 cr = abs(a->avg_r[i] - b->avg_r[i]);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
296 cg = abs(a->avg_g[i] - b->avg_g[i]);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
297 cb = abs(a->avg_b[i] - b->avg_b[i]);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
298
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
299 cd = cr + cg + cb;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
300 sim += cd + abs(cd - ld);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
301 ld = cd / 3;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
302 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
303 /* check for abort, if so return 0.0 */
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
304 if ((gdouble)sim / (255.0 * 1024.0 * 4.0) > min) return 0.0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
305 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
306
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
307 return (1.0 - ((gdouble)sim / (255.0 * 1024.0 * 4.0)) );
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
308 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
309 #endif
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
310
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
311 gdouble image_sim_compare(ImageSimilarityData *a, ImageSimilarityData *b)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
312 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
313 gint sim;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
314 gint i;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
315
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
316 if (!a || !b || !a->filled || !b->filled) return 0.0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
317
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
318 sim = 0.0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
319
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
320 for (i = 0; i < 1024; i++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
321 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
322 sim += abs(a->avg_r[i] - b->avg_r[i]);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
323 sim += abs(a->avg_g[i] - b->avg_g[i]);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
324 sim += abs(a->avg_b[i] - b->avg_b[i]);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
325 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
326
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
327 return 1.0 - ((gdouble)sim / (255.0 * 1024.0 * 3.0));
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
328 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
329
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
330 /* this uses a cutoff point so that it can abort early when it gets to
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
331 * a point that can simply no longer make the cut-off point.
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
332 */
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
333 gdouble image_sim_compare_fast(ImageSimilarityData *a, ImageSimilarityData *b, gdouble min)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
334 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
335 gint sim;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
336 gint i;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
337 gint j;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
338
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
339 #ifdef ALTERNATE_INCLUDE_COMPARE_CHANGE
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
340 if (alternate_enabled) return alternate_image_sim_compare_fast(a, b, min);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
341 #endif
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
342
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
343 if (!a || !b || !a->filled || !b->filled) return 0.0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
344
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
345 min = 1.0 - min;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
346 sim = 0.0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
347
927
d27b4184ceb8 Minor tidy up and optimization.
zas_
parents: 512
diff changeset
348 for (j = 0; j < 1024; j += 32)
9
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
349 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
350 for (i = j; i < j + 32; i++)
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
351 {
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
352 sim += abs(a->avg_r[i] - b->avg_r[i]);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
353 sim += abs(a->avg_g[i] - b->avg_g[i]);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
354 sim += abs(a->avg_b[i] - b->avg_b[i]);
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
355 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
356 /* check for abort, if so return 0.0 */
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
357 if ((gdouble)sim / (255.0 * 1024.0 * 3.0) > min) return 0.0;
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
358 }
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
359
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
360 return (1.0 - ((gdouble)sim / (255.0 * 1024.0 * 3.0)) );
d907d608745f Sync to GQview 1.5.9 release.
gqview
parents:
diff changeset
361 }
1055
1646720364cf Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents: 1003
diff changeset
362 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */