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