Mercurial > geeqie.yaz
comparison src/image.c @ 114:50fc73e08550
Mon Nov 27 01:23:23 2006 John Ellis <johne@verizon.net>
* bar_exif.c, cache-loader.c, pan-view.c: Pass new arg for exif_read().
* color-man.[ch]: Add color_man_new_embedded for using in-memory color
profiles.
* exif.[ch]: Add support for extracting color profiles embedded in jpeg
and tiff images. This resulted in a rewrite of the jpeg parser; both
to allow searching for any marker type, and to make the code readable.
* format_raw.c: Add color profile tag to the debug code.
* image.c, layout.c: Use embedded color profiles when found and
enabled, also add toggle for the option in color profile menu.
author | gqview |
---|---|
date | Mon, 27 Nov 2006 06:37:48 +0000 |
parents | 55166d93498d |
children | 53b2bfdcff69 |
comparison
equal
deleted
inserted
replaced
113:55166d93498d | 114:50fc73e08550 |
---|---|
163 *------------------------------------------------------------------- | 163 *------------------------------------------------------------------- |
164 * rotation, flip, etc. | 164 * rotation, flip, etc. |
165 *------------------------------------------------------------------- | 165 *------------------------------------------------------------------- |
166 */ | 166 */ |
167 | 167 |
168 static void image_alter_real(ImageWindow *imd, AlterType type, gint clamp, gint exif_rotated) | 168 static void image_alter_real(ImageWindow *imd, AlterType type, gint clamp) |
169 { | 169 { |
170 PixbufRenderer *pr; | 170 PixbufRenderer *pr; |
171 GdkPixbuf *new = NULL; | 171 GdkPixbuf *new = NULL; |
172 gint exif_rotate; | |
172 gint x, y; | 173 gint x, y; |
173 gint t; | 174 gint t; |
174 | 175 |
175 pr = (PixbufRenderer *)imd->pr; | 176 pr = (PixbufRenderer *)imd->pr; |
176 | 177 |
178 exif_rotate = (imd->delay_alter_type != ALTER_NONE && (imd->state & IMAGE_STATE_ROTATE_AUTO)); | |
177 imd->delay_alter_type = ALTER_NONE; | 179 imd->delay_alter_type = ALTER_NONE; |
178 | 180 |
179 if (!pr->pixbuf) return; | 181 if (!pr->pixbuf) return; |
180 | 182 |
181 x = pr->x_scroll + (pr->vis_width / 2); | 183 x = pr->x_scroll + (pr->vis_width / 2); |
224 pixbuf_renderer_set_pixbuf(pr, new, pr->zoom); | 226 pixbuf_renderer_set_pixbuf(pr, new, pr->zoom); |
225 g_object_unref(new); | 227 g_object_unref(new); |
226 | 228 |
227 if (clamp && pr->zoom != 0.0 && pr->scale != 0.0) | 229 if (clamp && pr->zoom != 0.0 && pr->scale != 0.0) |
228 { | 230 { |
229 if (exif_rotated) | 231 if (exif_rotate) |
230 { | 232 { |
231 switch (pr->scroll_reset) | 233 switch (pr->scroll_reset) |
232 { | 234 { |
233 case PR_SCROLL_RESET_NOCHANGE: | 235 case PR_SCROLL_RESET_NOCHANGE: |
234 break; | 236 break; |
247 (gint)((gdouble)y / pr->scale), | 249 (gint)((gdouble)y / pr->scale), |
248 0.50, 0.50); | 250 0.50, 0.50); |
249 } | 251 } |
250 } | 252 } |
251 | 253 |
254 static void image_post_process_alter(ImageWindow *imd, gint clamp) | |
255 { | |
256 if (imd->delay_alter_type != ALTER_NONE) | |
257 { | |
258 image_alter_real(imd, imd->delay_alter_type, clamp); | |
259 } | |
260 } | |
261 | |
252 static void image_post_process_color_cb(ColorMan *cm, ColorManReturnType type, gpointer data) | 262 static void image_post_process_color_cb(ColorMan *cm, ColorManReturnType type, gpointer data) |
253 { | 263 { |
254 ImageWindow *imd = data; | 264 ImageWindow *imd = data; |
255 | 265 |
256 color_man_free((ColorMan *)imd->cm); | 266 color_man_free((ColorMan *)imd->cm); |
257 imd->cm = NULL; | 267 imd->cm = NULL; |
258 imd->state |= IMAGE_STATE_COLOR_ADJ; | 268 imd->state |= IMAGE_STATE_COLOR_ADJ; |
259 | 269 |
260 if (type != COLOR_RETURN_IMAGE_CHANGED) | 270 if (type != COLOR_RETURN_IMAGE_CHANGED) |
261 { | 271 { |
262 image_post_process(imd, FALSE); | 272 image_post_process_alter(imd, FALSE); |
263 } | 273 } |
264 } | 274 } |
265 | 275 |
266 static gint image_post_process_color(ImageWindow *imd, gint start_row) | 276 static gint image_post_process_color(ImageWindow *imd, gint start_row, ExifData *exif) |
267 { | 277 { |
268 ColorMan *cm; | 278 ColorMan *cm; |
269 ColorManProfileType input_type; | 279 ColorManProfileType input_type; |
270 ColorManProfileType screen_type; | 280 ColorManProfileType screen_type; |
271 const gchar *input_file; | 281 const gchar *input_file; |
272 const gchar *screen_file; | 282 const gchar *screen_file; |
283 ExifItem *item = NULL; | |
273 | 284 |
274 if (imd->cm) return FALSE; | 285 if (imd->cm) return FALSE; |
275 | 286 |
276 if (imd->color_profile_input >= 1 && | 287 if (imd->color_profile_input >= 1 && |
277 imd->color_profile_input <= COLOR_PROFILE_INPUTS) | 288 imd->color_profile_input <= COLOR_PROFILE_INPUTS) |
308 else | 319 else |
309 { | 320 { |
310 return FALSE; | 321 return FALSE; |
311 } | 322 } |
312 | 323 |
313 cm = color_man_new(imd, | 324 if (imd->color_profile_use_image && exif) |
314 input_type, input_file, | 325 { |
315 screen_type, screen_file, | 326 item = exif_get_item(exif, "ColorProfile"); |
316 image_post_process_color_cb, imd); | 327 } |
328 if (item && item->format == EXIF_FORMAT_UNDEFINED) | |
329 { | |
330 if (debug) printf("Found embedded color profile\n"); | |
331 | |
332 cm = color_man_new_embedded(imd, | |
333 item->data, item->data_len, | |
334 screen_type, screen_file, | |
335 image_post_process_color_cb, imd); | |
336 } | |
337 else | |
338 { | |
339 cm = color_man_new(imd, | |
340 input_type, input_file, | |
341 screen_type, screen_file, | |
342 image_post_process_color_cb, imd); | |
343 } | |
344 | |
317 if (cm) | 345 if (cm) |
318 { | 346 { |
319 if (start_row > 0) cm->row = start_row; | 347 if (start_row > 0) cm->row = start_row; |
320 | 348 |
321 imd->cm = (gpointer)cm; | 349 imd->cm = (gpointer)cm; |
325 return FALSE; | 353 return FALSE; |
326 } | 354 } |
327 | 355 |
328 static void image_post_process(ImageWindow *imd, gint clamp) | 356 static void image_post_process(ImageWindow *imd, gint clamp) |
329 { | 357 { |
330 gint exif_rotated = FALSE; | 358 ExifData *exif = NULL; |
331 | 359 |
332 if (imd->color_profile_enable && | 360 if (!image_get_pixbuf(imd)) return; |
333 !(imd->state & IMAGE_STATE_COLOR_ADJ)) | 361 |
334 { | 362 if (exif_rotate_enable || |
335 if (image_post_process_color(imd, 0)) return; | 363 (imd->color_profile_enable && imd->color_profile_use_image) ) |
336 | 364 { |
337 /* fixme: note error to user */ | 365 exif = exif_read(imd->image_path, (imd->color_profile_enable && imd->color_profile_use_image)); |
338 imd->state |= IMAGE_STATE_COLOR_ADJ; | 366 } |
339 } | 367 |
340 | 368 if (exif_rotate_enable && exif) |
341 if (exif_rotate_enable && image_get_pixbuf(imd)) | 369 { |
342 { | |
343 ExifData *ed; | |
344 gint orientation; | 370 gint orientation; |
345 | 371 |
346 ed = exif_read(imd->image_path); | 372 if (exif_get_integer(exif, "Orientation", &orientation)) |
347 if (ed && exif_get_integer(ed, "Orientation", &orientation)) | |
348 { | 373 { |
374 gint rotate = TRUE; | |
375 | |
349 /* see http://jpegclub.org/exif_orientation.html | 376 /* see http://jpegclub.org/exif_orientation.html |
350 1 2 3 4 5 6 7 8 | 377 1 2 3 4 5 6 7 8 |
351 | 378 |
352 888888 888888 88 88 8888888888 88 88 8888888888 | 379 888888 888888 88 88 8888888888 88 88 8888888888 |
353 88 88 88 88 88 88 88 88 88 88 88 88 | 380 88 88 88 88 88 88 88 88 88 88 88 88 |
354 8888 8888 8888 8888 88 8888888888 8888888888 88 | 381 8888 8888 8888 8888 88 8888888888 8888888888 88 |
355 88 88 88 88 | 382 88 88 88 88 |
356 88 88 888888 888888 | 383 88 88 888888 888888 |
357 */ | 384 */ |
358 | |
359 switch (orientation) | 385 switch (orientation) |
360 { | 386 { |
361 case EXIF_ORIENTATION_TOP_LEFT: | 387 case EXIF_ORIENTATION_TOP_LEFT: |
362 /* normal -- nothing to do */ | 388 /* normal -- nothing to do */ |
389 rotate = FALSE; | |
363 break; | 390 break; |
364 case EXIF_ORIENTATION_TOP_RIGHT: | 391 case EXIF_ORIENTATION_TOP_RIGHT: |
365 /* mirrored */ | 392 /* mirrored */ |
366 imd->delay_alter_type = ALTER_MIRROR; | 393 imd->delay_alter_type = ALTER_MIRROR; |
367 exif_rotated = TRUE; | |
368 break; | 394 break; |
369 case EXIF_ORIENTATION_BOTTOM_RIGHT: | 395 case EXIF_ORIENTATION_BOTTOM_RIGHT: |
370 /* upside down */ | 396 /* upside down */ |
371 imd->delay_alter_type = ALTER_ROTATE_180; | 397 imd->delay_alter_type = ALTER_ROTATE_180; |
372 exif_rotated = TRUE; | |
373 break; | 398 break; |
374 case EXIF_ORIENTATION_BOTTOM_LEFT: | 399 case EXIF_ORIENTATION_BOTTOM_LEFT: |
375 /* flipped */ | 400 /* flipped */ |
376 imd->delay_alter_type = ALTER_FLIP; | 401 imd->delay_alter_type = ALTER_FLIP; |
377 exif_rotated = TRUE; | |
378 break; | 402 break; |
379 case EXIF_ORIENTATION_LEFT_TOP: | 403 case EXIF_ORIENTATION_LEFT_TOP: |
380 /* not implemented -- too wacky to fix in one step */ | 404 /* not implemented -- too wacky to fix in one step */ |
405 rotate = FALSE; | |
381 break; | 406 break; |
382 case EXIF_ORIENTATION_RIGHT_TOP: | 407 case EXIF_ORIENTATION_RIGHT_TOP: |
383 /* rotated -90 (270) */ | 408 /* rotated -90 (270) */ |
384 imd->delay_alter_type = ALTER_ROTATE_90; | 409 imd->delay_alter_type = ALTER_ROTATE_90; |
385 exif_rotated = TRUE; | |
386 break; | 410 break; |
387 case EXIF_ORIENTATION_RIGHT_BOTTOM: | 411 case EXIF_ORIENTATION_RIGHT_BOTTOM: |
388 /* not implemented -- too wacky to fix in one step */ | 412 /* not implemented -- too wacky to fix in one step */ |
413 rotate = FALSE; | |
389 break; | 414 break; |
390 case EXIF_ORIENTATION_LEFT_BOTTOM: | 415 case EXIF_ORIENTATION_LEFT_BOTTOM: |
391 /* rotated 90 */ | 416 /* rotated 90 */ |
392 imd->delay_alter_type = ALTER_ROTATE_90_CC; | 417 imd->delay_alter_type = ALTER_ROTATE_90_CC; |
393 exif_rotated = TRUE; | |
394 break; | 418 break; |
395 default: | 419 default: |
396 /* The other values are out of range */ | 420 /* The other values are out of range */ |
421 rotate = FALSE; | |
397 break; | 422 break; |
398 } | 423 } |
424 | |
425 if (rotate) imd->state |= IMAGE_STATE_COLOR_ADJ; | |
399 } | 426 } |
400 exif_free(ed); | 427 } |
401 } | 428 |
402 | 429 if (imd->color_profile_enable) |
403 if (imd->delay_alter_type != ALTER_NONE) | 430 { |
404 { | 431 if (!image_post_process_color(imd, 0, exif)) |
405 image_alter_real(imd, imd->delay_alter_type, clamp, exif_rotated); | 432 { |
406 } | 433 /* fixme: note error to user */ |
434 imd->state |= IMAGE_STATE_COLOR_ADJ; | |
435 } | |
436 } | |
437 | |
438 if (!imd->cm) image_post_process_alter(imd, clamp); | |
439 | |
440 exif_free(exif); | |
407 } | 441 } |
408 | 442 |
409 /* | 443 /* |
410 *------------------------------------------------------------------- | 444 *------------------------------------------------------------------- |
411 * read ahead (prebuffer) | 445 * read ahead (prebuffer) |
523 imd->image_path && imd->prev_path && strcmp(imd->image_path, imd->prev_path) == 0) | 557 imd->image_path && imd->prev_path && strcmp(imd->image_path, imd->prev_path) == 0) |
524 { | 558 { |
525 image_change_pixbuf(imd, imd->prev_pixbuf, image_zoom_get(imd)); | 559 image_change_pixbuf(imd, imd->prev_pixbuf, image_zoom_get(imd)); |
526 if (imd->prev_color_row >= 0) | 560 if (imd->prev_color_row >= 0) |
527 { | 561 { |
528 image_post_process_color(imd, imd->prev_color_row); | 562 ExifData *exif = NULL; |
563 | |
564 if (imd->color_profile_use_image) exif = exif_read(imd->image_path, TRUE); | |
565 image_post_process_color(imd, imd->prev_color_row, exif); | |
566 exif_free(exif); | |
529 } | 567 } |
530 success = TRUE; | 568 success = TRUE; |
531 } | 569 } |
532 else | 570 else |
533 { | 571 { |
1226 | 1264 |
1227 if (imd->il || imd->cm) | 1265 if (imd->il || imd->cm) |
1228 { | 1266 { |
1229 /* still loading, wait till done */ | 1267 /* still loading, wait till done */ |
1230 imd->delay_alter_type = type; | 1268 imd->delay_alter_type = type; |
1269 imd->state |= IMAGE_STATE_ROTATE_USER; | |
1270 | |
1271 if (imd->cm && (imd->state & IMAGE_STATE_ROTATE_AUTO)) | |
1272 { | |
1273 imd->state &= ~IMAGE_STATE_ROTATE_AUTO; | |
1274 } | |
1231 return; | 1275 return; |
1232 } | 1276 } |
1233 | 1277 |
1234 image_alter_real(imd, type, TRUE, FALSE); | 1278 image_alter_real(imd, type, TRUE); |
1235 } | 1279 } |
1236 | 1280 |
1237 void image_zoom_adjust(ImageWindow *imd, gdouble increment) | 1281 void image_zoom_adjust(ImageWindow *imd, gdouble increment) |
1238 { | 1282 { |
1239 pixbuf_renderer_zoom_adjust((PixbufRenderer *)imd->pr, increment); | 1283 pixbuf_renderer_zoom_adjust((PixbufRenderer *)imd->pr, increment); |