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