annotate src/similar.c @ 1757:8ecdf8445ef5

fixed and simplified sidecar grouping code
author nadvornik
date Thu, 24 Sep 2009 21:52:44 +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: */