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