Mercurial > geeqie.yaz
annotate src/cache.c @ 641:81441380d3be
When an option was successfully read, just continue to next line.
author | zas_ |
---|---|
date | Mon, 12 May 2008 10:46:23 +0000 |
parents | d4fe3a947929 |
children | 8268cbe682f1 |
rev | line source |
---|---|
9 | 1 /* |
196 | 2 * Geeqie |
9 | 3 * (C) 2004 John Ellis |
475 | 4 * Copyright (C) 2008 The Geeqie Team |
9 | 5 * |
6 * Author: John Ellis | |
7 * | |
8 * This software is released under the GNU General Public License (GNU GPL). | |
9 * Please read the included file COPYING for more information. | |
10 * This software comes with no warranty of any kind, use at your own risk! | |
11 */ | |
12 | |
281 | 13 #include "main.h" |
9 | 14 #include "cache.h" |
15 | |
507 | 16 #include "debug.h" |
9 | 17 #include "md5-util.h" |
538 | 18 #include "secure_save.h" |
9 | 19 #include "ui_fileops.h" |
20 | |
21 #include <utime.h> | |
22 #include <errno.h> | |
23 | |
24 | |
25 /* | |
26 *------------------------------------------------------------------- | |
27 * Cache data file format: | |
28 *------------------------------------------------------------------- | |
442 | 29 * |
9 | 30 * SIMcache |
535 | 31 * #comment |
9 | 32 * Dimensions=[<width> x <height>] |
37
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
33 * Date=[<value in time_t format, or -1 if no embedded date>] |
9 | 34 * Checksum=[<value>] |
35 * MD5sum=[<32 character ascii text digest>] | |
36 * SimilarityGrid[32 x 32]=<3072 bytes of data (1024 pixels in RGB format, 1 pixel is 24bits)> | |
442 | 37 * |
38 * | |
9 | 39 * The first line (9 bytes) indicates it is a SIMcache format file. (new line char must exist) |
40 * Comment lines starting with a # are ignored up to a new line. | |
41 * All data lines should end with a new line char. | |
42 * Format is very strict, data must begin with the char immediately following '='. | |
43 * Currently SimilarityGrid is always assumed to be 32 x 32 RGB. | |
44 */ | |
45 | |
46 | |
47 /* | |
48 *------------------------------------------------------------------- | |
49 * sim cache data | |
50 *------------------------------------------------------------------- | |
51 */ | |
52 | |
53 CacheData *cache_sim_data_new(void) | |
54 { | |
55 CacheData *cd; | |
56 | |
57 cd = g_new0(CacheData, 1); | |
37
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
58 cd->date = -1; |
9 | 59 |
60 return cd; | |
61 } | |
62 | |
63 void cache_sim_data_free(CacheData *cd) | |
64 { | |
65 if (!cd) return; | |
66 | |
67 g_free(cd->path); | |
68 image_sim_free(cd->sim); | |
69 g_free(cd); | |
70 } | |
71 | |
72 /* | |
73 *------------------------------------------------------------------- | |
74 * sim cache write | |
75 *------------------------------------------------------------------- | |
76 */ | |
77 | |
538 | 78 static gint cache_sim_write_dimensions(SecureSaveInfo *ssi, CacheData *cd) |
9 | 79 { |
538 | 80 if (!cd || !cd->dimensions) return FALSE; |
9 | 81 |
538 | 82 secure_fprintf(ssi, "Dimensions=[%d x %d]\n", cd->width, cd->height); |
9 | 83 |
84 return TRUE; | |
85 } | |
86 | |
538 | 87 static gint cache_sim_write_date(SecureSaveInfo *ssi, CacheData *cd) |
37
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
88 { |
538 | 89 if (!cd || !cd->have_date) return FALSE; |
37
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
90 |
538 | 91 secure_fprintf(ssi, "Date=[%ld]\n", cd->date); |
37
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
92 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
93 return TRUE; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
94 } |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
95 |
538 | 96 static gint cache_sim_write_checksum(SecureSaveInfo *ssi, CacheData *cd) |
9 | 97 { |
538 | 98 if (!cd || !cd->have_checksum) return FALSE; |
9 | 99 |
538 | 100 secure_fprintf(ssi, "Checksum=[%ld]\n", cd->checksum); |
9 | 101 |
102 return TRUE; | |
103 } | |
104 | |
538 | 105 static gint cache_sim_write_md5sum(SecureSaveInfo *ssi, CacheData *cd) |
9 | 106 { |
107 gchar *text; | |
108 | |
538 | 109 if (!cd || !cd->have_md5sum) return FALSE; |
9 | 110 |
111 text = md5_digest_to_text(cd->md5sum); | |
538 | 112 secure_fprintf(ssi, "MD5sum=[%s]\n", text); |
9 | 113 g_free(text); |
114 | |
115 return TRUE; | |
116 } | |
117 | |
538 | 118 static gint cache_sim_write_similarity(SecureSaveInfo *ssi, CacheData *cd) |
9 | 119 { |
539
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
120 guint x, y; |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
121 guint8 buf[3 * 32]; |
9 | 122 |
539
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
123 if (!cd || !cd->similarity || !cd->sim || !cd->sim->filled) return FALSE; |
9 | 124 |
539
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
125 secure_fprintf(ssi, "SimilarityGrid[32 x 32]="); |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
126 for (y = 0; y < 32; y++) |
9 | 127 { |
539
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
128 guint s = y * 32; |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
129 guint8 *avg_r = &cd->sim->avg_r[s]; |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
130 guint8 *avg_g = &cd->sim->avg_g[s]; |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
131 guint8 *avg_b = &cd->sim->avg_b[s]; |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
132 guint n = 0; |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
133 |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
134 for (x = 0; x < 32; x++) |
9 | 135 { |
539
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
136 buf[n++] = avg_r[x]; |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
137 buf[n++] = avg_g[x]; |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
138 buf[n++] = avg_b[x]; |
9 | 139 } |
140 | |
539
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
141 secure_fwrite(buf, sizeof(buf), 1, ssi); |
9 | 142 } |
143 | |
539
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
144 secure_fputc(ssi, '\n'); |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
145 |
58b7c38d5a5b
cache_sim_write_similarity(): cleanup and simplification.
zas_
parents:
538
diff
changeset
|
146 return TRUE; |
9 | 147 } |
148 | |
149 gint cache_sim_data_save(CacheData *cd) | |
150 { | |
538 | 151 SecureSaveInfo *ssi; |
9 | 152 gchar *pathl; |
153 | |
154 if (!cd || !cd->path) return FALSE; | |
155 | |
156 pathl = path_from_utf8(cd->path); | |
538 | 157 ssi = secure_open(pathl); |
9 | 158 g_free(pathl); |
159 | |
538 | 160 if (!ssi) |
9 | 161 { |
162 printf("Unable to save sim cache data: %s\n", cd->path); | |
163 return FALSE; | |
164 } | |
165 | |
538 | 166 secure_fprintf(ssi, "SIMcache\n#%s %s\n", PACKAGE, VERSION); |
167 cache_sim_write_dimensions(ssi, cd); | |
168 cache_sim_write_date(ssi, cd); | |
169 cache_sim_write_checksum(ssi, cd); | |
170 cache_sim_write_md5sum(ssi, cd); | |
171 cache_sim_write_similarity(ssi, cd); | |
9 | 172 |
538 | 173 if (secure_close(ssi)) |
174 { | |
175 printf_term(_("error saving sim cache data: %s\nerror: %s\n"), cd->path, | |
176 secsave_strerror(secsave_errno)); | |
177 return FALSE; | |
178 } | |
9 | 179 |
180 return TRUE; | |
181 } | |
182 | |
183 /* | |
184 *------------------------------------------------------------------- | |
185 * sim cache read | |
186 *------------------------------------------------------------------- | |
187 */ | |
188 | |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
189 static gint cache_sim_read_skipline(FILE *f, int s) |
9 | 190 { |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
191 if (!f) return FALSE; |
9 | 192 |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
193 if (fseek(f, 0 - s, SEEK_CUR) == 0) |
9 | 194 { |
195 char b; | |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
196 while (fread(&b, sizeof(b), 1, f) == 1) |
9 | 197 { |
198 if (b == '\n') return TRUE; | |
199 } | |
200 return TRUE; | |
201 } | |
202 | |
203 return FALSE; | |
204 } | |
205 | |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
206 static gint cache_sim_read_comment(FILE *f, char *buf, int s, CacheData *cd) |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
207 { |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
208 if (!f || !buf || !cd) return FALSE; |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
209 |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
210 if (s < 1 || buf[0] != '#') return FALSE; |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
211 |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
212 return cache_sim_read_skipline(f, s - 1); |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
213 } |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
214 |
9 | 215 static gint cache_sim_read_dimensions(FILE *f, char *buf, int s, CacheData *cd) |
216 { | |
217 if (!f || !buf || !cd) return FALSE; | |
218 | |
219 if (s < 10 || strncmp("Dimensions", buf, 10) != 0) return FALSE; | |
220 | |
221 if (fseek(f, - s, SEEK_CUR) == 0) | |
222 { | |
223 char b; | |
224 char buf[1024]; | |
225 gint p = 0; | |
226 gint w, h; | |
227 | |
228 b = 'X'; | |
229 while (b != '[') | |
230 { | |
231 if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; | |
232 } | |
540 | 233 while (b != ']' && p < sizeof(buf) - 1) |
9 | 234 { |
235 if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; | |
236 buf[p] = b; | |
237 p++; | |
238 } | |
239 | |
240 while (b != '\n') | |
241 { | |
242 if (fread(&b, sizeof(b), 1, f) != 1) break; | |
243 } | |
244 | |
245 buf[p] = '\0'; | |
246 if (sscanf(buf, "%d x %d", &w, &h) != 2) return FALSE; | |
247 | |
248 cd->width = w; | |
249 cd->height = h; | |
250 cd->dimensions = TRUE; | |
251 | |
252 return TRUE; | |
253 } | |
254 | |
255 return FALSE; | |
256 } | |
257 | |
37
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
258 static gint cache_sim_read_date(FILE *f, char *buf, int s, CacheData *cd) |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
259 { |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
260 if (!f || !buf || !cd) return FALSE; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
261 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
262 if (s < 4 || strncmp("Date", buf, 4) != 0) return FALSE; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
263 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
264 if (fseek(f, - s, SEEK_CUR) == 0) |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
265 { |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
266 char b; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
267 char buf[1024]; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
268 gint p = 0; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
269 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
270 b = 'X'; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
271 while (b != '[') |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
272 { |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
273 if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
274 } |
540 | 275 while (b != ']' && p < sizeof(buf) - 1) |
37
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
276 { |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
277 if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
278 buf[p] = b; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
279 p++; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
280 } |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
281 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
282 while (b != '\n') |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
283 { |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
284 if (fread(&b, sizeof(b), 1, f) != 1) break; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
285 } |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
286 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
287 buf[p] = '\0'; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
288 cd->date = strtol(buf, NULL, 10); |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
289 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
290 cd->have_date = TRUE; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
291 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
292 return TRUE; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
293 } |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
294 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
295 return FALSE; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
296 } |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
297 |
9 | 298 static gint cache_sim_read_checksum(FILE *f, char *buf, int s, CacheData *cd) |
299 { | |
300 if (!f || !buf || !cd) return FALSE; | |
301 | |
302 if (s < 8 || strncmp("Checksum", buf, 8) != 0) return FALSE; | |
303 | |
304 if (fseek(f, - s, SEEK_CUR) == 0) | |
305 { | |
306 char b; | |
307 char buf[1024]; | |
308 gint p = 0; | |
309 | |
310 b = 'X'; | |
311 while (b != '[') | |
312 { | |
313 if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; | |
314 } | |
540 | 315 while (b != ']' && p < sizeof(buf) - 1) |
9 | 316 { |
317 if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; | |
318 buf[p] = b; | |
319 p++; | |
320 } | |
321 | |
322 while (b != '\n') | |
323 { | |
324 if (fread(&b, sizeof(b), 1, f) != 1) break; | |
325 } | |
326 | |
327 buf[p] = '\0'; | |
328 cd->checksum = strtol(buf, NULL, 10); | |
329 | |
330 cd->have_checksum = TRUE; | |
331 | |
332 return TRUE; | |
333 } | |
334 | |
335 return FALSE; | |
336 } | |
337 | |
338 static gint cache_sim_read_md5sum(FILE *f, char *buf, int s, CacheData *cd) | |
339 { | |
340 if (!f || !buf || !cd) return FALSE; | |
341 | |
342 if (s < 8 || strncmp("MD5sum", buf, 6) != 0) return FALSE; | |
343 | |
344 if (fseek(f, - s, SEEK_CUR) == 0) | |
345 { | |
346 char b; | |
347 char buf[64]; | |
348 gint p = 0; | |
349 | |
350 b = 'X'; | |
351 while (b != '[') | |
352 { | |
353 if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; | |
354 } | |
540 | 355 while (b != ']' && p < sizeof(buf) - 1) |
9 | 356 { |
357 if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; | |
358 buf[p] = b; | |
359 p++; | |
360 } | |
361 while (b != '\n') | |
362 { | |
363 if (fread(&b, sizeof(b), 1, f) != 1) break; | |
364 } | |
365 | |
366 buf[p] = '\0'; | |
367 cd->have_md5sum = md5_digest_from_text(buf, cd->md5sum); | |
368 | |
369 return TRUE; | |
370 } | |
371 | |
372 return FALSE; | |
373 } | |
374 | |
375 static gint cache_sim_read_similarity(FILE *f, char *buf, int s, CacheData *cd) | |
376 { | |
377 if (!f || !buf || !cd) return FALSE; | |
378 | |
379 if (s < 11 || strncmp("Similarity", buf, 10) != 0) return FALSE; | |
380 | |
381 if (strncmp("Grid[32 x 32]", buf + 10, 13) != 0) return FALSE; | |
382 | |
383 if (fseek(f, - s, SEEK_CUR) == 0) | |
384 { | |
385 char b; | |
386 guint8 pixel_buf[3]; | |
387 ImageSimilarityData *sd; | |
388 gint x, y; | |
389 | |
390 b = 'X'; | |
391 while (b != '=') | |
392 { | |
393 if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; | |
394 } | |
395 | |
396 if (cd->sim) | |
397 { | |
398 /* use current sim that may already contain data we will not touch here */ | |
399 sd = cd->sim; | |
400 cd->sim = NULL; | |
401 cd->similarity = FALSE; | |
402 } | |
403 else | |
404 { | |
405 sd = image_sim_new(); | |
406 } | |
407 | |
408 for (y = 0; y < 32; y++) | |
409 { | |
410 gint s = y * 32; | |
411 for (x = 0; x < 32; x++) | |
412 { | |
413 if (fread(&pixel_buf, sizeof(pixel_buf), 1, f) != 1) | |
414 { | |
415 image_sim_free(sd); | |
416 return FALSE; | |
417 } | |
418 sd->avg_r[s + x] = pixel_buf[0]; | |
419 sd->avg_g[s + x] = pixel_buf[1]; | |
420 sd->avg_b[s + x] = pixel_buf[2]; | |
421 } | |
422 } | |
423 | |
424 if (fread(&b, sizeof(b), 1, f) == 1) | |
425 { | |
426 if (b != '\n') fseek(f, -1, SEEK_CUR); | |
427 } | |
428 | |
429 cd->sim = sd; | |
430 cd->sim->filled = TRUE; | |
431 cd->similarity = TRUE; | |
432 | |
433 return TRUE; | |
434 } | |
435 | |
436 return FALSE; | |
437 } | |
438 | |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
439 #define CACHE_LOAD_LINE_NOISE 8 |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
440 |
9 | 441 CacheData *cache_sim_data_load(const gchar *path) |
442 { | |
443 FILE *f; | |
444 CacheData *cd = NULL; | |
445 char buf[32]; | |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
446 gint success = CACHE_LOAD_LINE_NOISE; |
9 | 447 gchar *pathl; |
448 | |
449 if (!path) return NULL; | |
450 | |
451 pathl = path_from_utf8(path); | |
452 f = fopen(pathl, "r"); | |
453 g_free(pathl); | |
454 | |
455 if (!f) return NULL; | |
456 | |
457 cd = cache_sim_data_new(); | |
458 cd->path = g_strdup(path); | |
459 | |
460 if (fread(&buf, sizeof(char), 9, f) != 9 || | |
461 strncmp(buf, "SIMcache", 8) != 0) | |
462 { | |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
463 DEBUG_1("%s is not a cache file", cd->path); |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
464 success = 0; |
9 | 465 } |
466 | |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
467 while (success > 0) |
9 | 468 { |
469 int s; | |
470 s = fread(&buf, sizeof(char), sizeof(buf), f); | |
471 | |
472 if (s < 1) | |
473 { | |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
474 success = 0; |
9 | 475 } |
476 else | |
477 { | |
478 if (!cache_sim_read_comment(f, buf, s, cd) && | |
479 !cache_sim_read_dimensions(f, buf, s, cd) && | |
37
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
480 !cache_sim_read_date(f, buf, s, cd) && |
9 | 481 !cache_sim_read_checksum(f, buf, s, cd) && |
482 !cache_sim_read_md5sum(f, buf, s, cd) && | |
483 !cache_sim_read_similarity(f, buf, s, cd)) | |
484 { | |
65
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
485 if (!cache_sim_read_skipline(f, s)) |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
486 { |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
487 success = 0; |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
488 } |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
489 else |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
490 { |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
491 success--; |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
492 } |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
493 } |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
494 else |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
495 { |
322bb41c9b9e
Mon Aug 15 18:27:38 2005 John Ellis <johne@verizon.net>
gqview
parents:
39
diff
changeset
|
496 success = CACHE_LOAD_LINE_NOISE; |
9 | 497 } |
498 } | |
499 } | |
500 | |
501 fclose(f); | |
502 | |
39
64068b1bab89
Thu Apr 14 10:44:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
37
diff
changeset
|
503 if (!cd->dimensions && |
64068b1bab89
Thu Apr 14 10:44:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
37
diff
changeset
|
504 !cd->have_date && |
64068b1bab89
Thu Apr 14 10:44:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
37
diff
changeset
|
505 !cd->have_checksum && |
64068b1bab89
Thu Apr 14 10:44:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
37
diff
changeset
|
506 !cd->have_md5sum && |
64068b1bab89
Thu Apr 14 10:44:00 2005 John Ellis <johne@verizon.net>
gqview
parents:
37
diff
changeset
|
507 !cd->similarity) |
9 | 508 { |
509 cache_sim_data_free(cd); | |
510 cd = NULL; | |
511 } | |
512 | |
513 return cd; | |
514 } | |
515 | |
516 /* | |
517 *------------------------------------------------------------------- | |
518 * sim cache setting | |
519 *------------------------------------------------------------------- | |
520 */ | |
521 | |
522 void cache_sim_data_set_dimensions(CacheData *cd, gint w, gint h) | |
523 { | |
524 if (!cd) return; | |
525 | |
526 cd->width = w; | |
527 cd->height = h; | |
528 cd->dimensions = TRUE; | |
529 } | |
530 | |
37
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
531 void cache_sim_data_set_date(CacheData *cd, time_t date) |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
532 { |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
533 if (!cd) return; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
534 |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
535 cd->date = date; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
536 cd->have_date = TRUE; |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
537 } |
67ba4381497e
Wed Apr 13 18:16:14 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
538 |
9 | 539 void cache_sim_data_set_checksum(CacheData *cd, long checksum) |
540 { | |
541 if (!cd) return; | |
542 | |
543 cd->checksum = checksum; | |
544 cd->have_checksum = TRUE; | |
545 } | |
546 | |
547 void cache_sim_data_set_md5sum(CacheData *cd, guchar digest[16]) | |
548 { | |
549 gint i; | |
550 | |
551 if (!cd) return; | |
552 | |
553 for (i = 0; i < 16; i++) | |
554 { | |
555 cd->md5sum[i] = digest[i]; | |
556 } | |
557 cd->have_md5sum = TRUE; | |
558 } | |
559 | |
560 void cache_sim_data_set_similarity(CacheData *cd, ImageSimilarityData *sd) | |
561 { | |
562 if (!cd || !sd || !sd->filled) return; | |
563 | |
564 if (!cd->sim) cd->sim = image_sim_new(); | |
565 | |
566 memcpy(cd->sim->avg_r, sd->avg_r, 1024); | |
567 memcpy(cd->sim->avg_g, sd->avg_g, 1024); | |
568 memcpy(cd->sim->avg_b, sd->avg_b, 1024); | |
569 cd->sim->filled = TRUE; | |
570 | |
571 cd->similarity = TRUE; | |
572 } | |
573 | |
574 gint cache_sim_data_filled(ImageSimilarityData *sd) | |
575 { | |
576 if (!sd) return FALSE; | |
577 return sd->filled; | |
578 } | |
579 | |
580 /* | |
581 *------------------------------------------------------------------- | |
582 * cache path location utils | |
583 *------------------------------------------------------------------- | |
584 */ | |
585 | |
586 /* warning: this func modifies path string contents!, on fail it is set to fail point */ | |
587 gint cache_ensure_dir_exists(gchar *path, mode_t mode) | |
588 { | |
589 if (!path) return FALSE; | |
590 | |
591 if (!isdir(path)) | |
592 { | |
593 gchar *p = path; | |
594 while (p[0] != '\0') | |
595 { | |
596 p++; | |
597 if (p[0] == '/' || p[0] == '\0') | |
598 { | |
599 gint end = TRUE; | |
600 if (p[0] != '\0') | |
601 { | |
602 p[0] = '\0'; | |
603 end = FALSE; | |
604 } | |
605 if (!isdir(path)) | |
606 { | |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
607 DEBUG_1("creating sub dir:%s", path); |
9 | 608 if (!mkdir_utf8(path, mode)) |
609 { | |
610 printf("create dir failed: %s\n", path); | |
611 return FALSE; | |
612 } | |
613 } | |
614 if (!end) p[0] = '/'; | |
615 } | |
616 } | |
617 } | |
618 return TRUE; | |
619 } | |
620 | |
621 static void cache_path_parts(CacheType type, | |
622 const gchar **cache_rc, const gchar **cache_local, const gchar **cache_ext) | |
623 { | |
624 switch (type) | |
625 { | |
626 case CACHE_TYPE_THUMB: | |
283 | 627 *cache_rc = GQ_CACHE_RC_THUMB; |
628 *cache_local = GQ_CACHE_LOCAL_THUMB; | |
629 *cache_ext = GQ_CACHE_EXT_THUMB; | |
9 | 630 break; |
631 case CACHE_TYPE_SIM: | |
283 | 632 *cache_rc = GQ_CACHE_RC_THUMB; |
633 *cache_local = GQ_CACHE_LOCAL_THUMB; | |
634 *cache_ext = GQ_CACHE_EXT_SIM; | |
9 | 635 break; |
636 case CACHE_TYPE_METADATA: | |
283 | 637 *cache_rc = GQ_CACHE_RC_METADATA; |
638 *cache_local = GQ_CACHE_LOCAL_METADATA; | |
639 *cache_ext = GQ_CACHE_EXT_METADATA; | |
9 | 640 break; |
641 } | |
642 } | |
643 | |
644 gchar *cache_get_location(CacheType type, const gchar *source, gint include_name, mode_t *mode) | |
645 { | |
646 gchar *path = NULL; | |
647 gchar *base; | |
648 gchar *name = NULL; | |
649 const gchar *cache_rc; | |
650 const gchar *cache_local; | |
651 const gchar *cache_ext; | |
652 | |
653 if (!source) return NULL; | |
654 | |
655 cache_path_parts(type, &cache_rc, &cache_local, &cache_ext); | |
656 | |
657 base = remove_level_from_path(source); | |
658 if (include_name) | |
659 { | |
660 name = g_strconcat("/", filename_from_path(source), NULL); | |
661 } | |
662 else | |
663 { | |
664 cache_ext = NULL; | |
665 } | |
666 | |
333 | 667 if (((type != CACHE_TYPE_METADATA && options->thumbnails.cache_into_dirs) || |
318 | 668 (type == CACHE_TYPE_METADATA && options->enable_metadata_dirs)) && |
9 | 669 access_file(base, W_OK)) |
670 { | |
671 path = g_strconcat(base, "/", cache_local, name, cache_ext, NULL); | |
672 if (mode) *mode = 0775; | |
673 } | |
674 | |
675 if (!path) | |
676 { | |
677 path = g_strconcat(homedir(), "/", cache_rc, base, name, cache_ext, NULL); | |
678 if (mode) *mode = 0755; | |
679 } | |
680 | |
681 g_free(base); | |
682 if (name) g_free(name); | |
683 | |
684 return path; | |
685 } | |
686 | |
687 gchar *cache_find_location(CacheType type, const gchar *source) | |
688 { | |
689 gchar *path; | |
690 const gchar *name; | |
691 gchar *base; | |
692 const gchar *cache_rc; | |
693 const gchar *cache_local; | |
694 const gchar *cache_ext; | |
695 gint prefer_local; | |
696 | |
697 if (!source) return NULL; | |
698 | |
699 cache_path_parts(type, &cache_rc, &cache_local, &cache_ext); | |
700 | |
701 name = filename_from_path(source); | |
702 base = remove_level_from_path(source); | |
703 | |
704 if (type == CACHE_TYPE_METADATA) | |
705 { | |
318 | 706 prefer_local = options->enable_metadata_dirs; |
9 | 707 } |
708 else | |
709 { | |
333 | 710 prefer_local = options->thumbnails.cache_into_dirs; |
9 | 711 } |
712 | |
713 if (prefer_local) | |
714 { | |
715 path = g_strconcat(base, "/", cache_local, "/", name, cache_ext, NULL); | |
716 } | |
717 else | |
718 { | |
719 path = g_strconcat(homedir(), "/", cache_rc, source, cache_ext, NULL); | |
720 } | |
721 | |
722 if (!isfile(path)) | |
723 { | |
724 g_free(path); | |
725 | |
726 /* try the opposite method if not found */ | |
727 if (!prefer_local) | |
728 { | |
729 path = g_strconcat(base, "/", cache_local, "/", name, cache_ext, NULL); | |
730 } | |
731 else | |
732 { | |
733 path = g_strconcat(homedir(), "/", cache_rc, source, cache_ext, NULL); | |
734 } | |
735 | |
736 if (!isfile(path)) | |
737 { | |
738 g_free(path); | |
739 path = NULL; | |
740 } | |
741 } | |
742 | |
743 g_free(base); | |
744 | |
745 return path; | |
746 } | |
747 | |
748 gint cache_time_valid(const gchar *cache, const gchar *path) | |
749 { | |
750 struct stat cache_st; | |
751 struct stat path_st; | |
752 gchar *cachel; | |
753 gchar *pathl; | |
754 gint ret = FALSE; | |
755 | |
756 if (!cache || !path) return FALSE; | |
757 | |
758 cachel = path_from_utf8(cache); | |
759 pathl = path_from_utf8(path); | |
760 | |
761 if (stat(cachel, &cache_st) == 0 && | |
762 stat(pathl, &path_st) == 0) | |
763 { | |
764 if (cache_st.st_mtime == path_st.st_mtime) | |
765 { | |
766 ret = TRUE; | |
767 } | |
768 else if (cache_st.st_mtime > path_st.st_mtime) | |
769 { | |
770 struct utimbuf ut; | |
771 | |
772 ut.actime = ut.modtime = cache_st.st_mtime; | |
773 if (utime(cachel, &ut) < 0 && | |
774 errno == EPERM) | |
775 { | |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
776 DEBUG_1("cache permission workaround: %s", cachel); |
9 | 777 ret = TRUE; |
778 } | |
779 } | |
780 } | |
781 | |
782 g_free(pathl); | |
783 g_free(cachel); | |
784 | |
785 return ret; | |
786 } |