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