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);