diff 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
line wrap: on
line diff
--- a/src/image.c	Sat Nov 25 03:00:33 2006 +0000
+++ b/src/image.c	Mon Nov 27 06:37:48 2006 +0000
@@ -165,15 +165,17 @@
  *-------------------------------------------------------------------
  */
 
-static void image_alter_real(ImageWindow *imd, AlterType type, gint clamp, gint exif_rotated)
+static void image_alter_real(ImageWindow *imd, AlterType type, gint clamp)
 {
 	PixbufRenderer *pr;
 	GdkPixbuf *new = NULL;
+	gint exif_rotate;
 	gint x, y;
 	gint t;
 
 	pr = (PixbufRenderer *)imd->pr;
 
+	exif_rotate = (imd->delay_alter_type != ALTER_NONE && (imd->state & IMAGE_STATE_ROTATE_AUTO));
 	imd->delay_alter_type = ALTER_NONE;
 
 	if (!pr->pixbuf) return;
@@ -226,7 +228,7 @@
 
 	if (clamp && pr->zoom != 0.0 && pr->scale != 0.0)
 		{
-		if (exif_rotated)
+		if (exif_rotate)
 			{
 			switch (pr->scroll_reset)
 				{
@@ -249,6 +251,14 @@
 		}
 }
 
+static void image_post_process_alter(ImageWindow *imd, gint clamp)
+{
+	if (imd->delay_alter_type != ALTER_NONE)
+		{
+		image_alter_real(imd, imd->delay_alter_type, clamp);
+		}
+}
+
 static void image_post_process_color_cb(ColorMan *cm, ColorManReturnType type, gpointer data)
 {
 	ImageWindow *imd = data;
@@ -259,17 +269,18 @@
 
 	if (type != COLOR_RETURN_IMAGE_CHANGED)
 		{
-		image_post_process(imd, FALSE);
+		image_post_process_alter(imd, FALSE);
 		}
 }
 
-static gint image_post_process_color(ImageWindow *imd, gint start_row)
+static gint image_post_process_color(ImageWindow *imd, gint start_row, ExifData *exif)
 {
 	ColorMan *cm;
 	ColorManProfileType input_type;
 	ColorManProfileType screen_type;
 	const gchar *input_file;
 	const gchar *screen_file;
+	ExifItem *item = NULL;
 
 	if (imd->cm) return FALSE;
 
@@ -310,10 +321,27 @@
 		return FALSE;
 		}
 
-	cm = color_man_new(imd,
-			   input_type, input_file,
-			   screen_type, screen_file,
-			   image_post_process_color_cb, imd);
+	if (imd->color_profile_use_image && exif)
+		{
+		item = exif_get_item(exif, "ColorProfile");
+		}
+	if (item && item->format == EXIF_FORMAT_UNDEFINED)
+		{
+		if (debug) printf("Found embedded color profile\n");
+
+		cm = color_man_new_embedded(imd,
+					    item->data, item->data_len,
+					    screen_type, screen_file,
+					    image_post_process_color_cb, imd);
+		}
+	else
+		{
+		cm = color_man_new(imd,
+				   input_type, input_file,
+				   screen_type, screen_file,
+				   image_post_process_color_cb, imd);
+		}
+
 	if (cm)
 		{
 		if (start_row > 0) cm->row = start_row;
@@ -327,25 +355,24 @@
 
 static void image_post_process(ImageWindow *imd, gint clamp)
 {
-	gint exif_rotated = FALSE;
+	ExifData *exif = NULL;
 
-	if (imd->color_profile_enable &&
-	    !(imd->state & IMAGE_STATE_COLOR_ADJ))
+	if (!image_get_pixbuf(imd)) return;
+
+	if (exif_rotate_enable ||
+	    (imd->color_profile_enable && imd->color_profile_use_image) )
 		{
-		if (image_post_process_color(imd, 0)) return;
-
-		/* fixme: note error to user */
-		imd->state |= IMAGE_STATE_COLOR_ADJ;
+		exif = exif_read(imd->image_path, (imd->color_profile_enable && imd->color_profile_use_image));
 		}
 
-	if (exif_rotate_enable && image_get_pixbuf(imd))
+	if (exif_rotate_enable && exif)
 		{
-		ExifData *ed;
 		gint orientation;
 
-		ed = exif_read(imd->image_path);
-		if (ed && exif_get_integer(ed, "Orientation", &orientation))
+		if (exif_get_integer(exif, "Orientation", &orientation))
 			{
+			gint rotate = TRUE;
+
 			/* see http://jpegclub.org/exif_orientation.html 
 			  1        2       3      4         5            6           7          8
 
@@ -355,55 +382,62 @@
 			88          88      88  88
 			88          88  888888  888888
 			*/
-
 			switch (orientation)
 				{
 				case EXIF_ORIENTATION_TOP_LEFT:
 					/* normal -- nothing to do */
+					rotate = FALSE;
 					break;
 				case EXIF_ORIENTATION_TOP_RIGHT:
 					/* mirrored */
 					imd->delay_alter_type = ALTER_MIRROR;
-					exif_rotated = TRUE;
 					break;
 				case EXIF_ORIENTATION_BOTTOM_RIGHT:
 					/* upside down */
 					imd->delay_alter_type = ALTER_ROTATE_180;
-					exif_rotated = TRUE;
 					break;
 				case EXIF_ORIENTATION_BOTTOM_LEFT:
 					/* flipped */
 					imd->delay_alter_type = ALTER_FLIP;
-					exif_rotated = TRUE;
 					break;
 				case EXIF_ORIENTATION_LEFT_TOP:
 					/* not implemented -- too wacky to fix in one step */
+					rotate = FALSE;
 					break;
 				case EXIF_ORIENTATION_RIGHT_TOP:
 					/* rotated -90 (270) */
 					imd->delay_alter_type = ALTER_ROTATE_90;
-					exif_rotated = TRUE;
 					break;
 				case EXIF_ORIENTATION_RIGHT_BOTTOM:
 					/* not implemented -- too wacky to fix in one step */
+					rotate = FALSE;
 					break;
 				case EXIF_ORIENTATION_LEFT_BOTTOM:
 					/* rotated 90 */
 					imd->delay_alter_type = ALTER_ROTATE_90_CC;
-					exif_rotated = TRUE;
 					break;
 				default:
 					/* The other values are out of range */
+					rotate = FALSE;
 					break;
 				}
+
+			if (rotate) imd->state |= IMAGE_STATE_COLOR_ADJ;
 			}
-		exif_free(ed);
 		}
 
-	if (imd->delay_alter_type != ALTER_NONE)
+	if (imd->color_profile_enable)
 		{
-		image_alter_real(imd, imd->delay_alter_type, clamp, exif_rotated);
+		if (!image_post_process_color(imd, 0, exif))
+			{
+			/* fixme: note error to user */
+			imd->state |= IMAGE_STATE_COLOR_ADJ;
+			}
 		}
+
+	if (!imd->cm) image_post_process_alter(imd, clamp);
+
+	exif_free(exif);
 }
 
 /*
@@ -525,7 +559,11 @@
 		image_change_pixbuf(imd, imd->prev_pixbuf, image_zoom_get(imd));
 		if (imd->prev_color_row >= 0)
 			{
-			image_post_process_color(imd, imd->prev_color_row);
+			ExifData *exif = NULL;
+
+			if (imd->color_profile_use_image) exif = exif_read(imd->image_path, TRUE);
+			image_post_process_color(imd, imd->prev_color_row, exif);
+			exif_free(exif);
 			}
 		success = TRUE;
 		}
@@ -1228,10 +1266,16 @@
 		{
 		/* still loading, wait till done */
 		imd->delay_alter_type = type;
+		imd->state |= IMAGE_STATE_ROTATE_USER;
+
+		if (imd->cm && (imd->state & IMAGE_STATE_ROTATE_AUTO))
+			{
+			imd->state &= ~IMAGE_STATE_ROTATE_AUTO;
+			}
 		return;
 		}
 
-	image_alter_real(imd, type, TRUE, FALSE);
+	image_alter_real(imd, type, TRUE);
 }
 
 void image_zoom_adjust(ImageWindow *imd, gdouble increment)