[gthumb: 82/129] jpeg info: fixed loading of image dimensions



commit 24825ccdeee3f77d5fdca1e15d2d43656f7f0b4d
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Mon Apr 25 17:32:22 2011 +0200

    jpeg info: fixed loading of image dimensions

 extensions/jpeg_utils/jpeg-info.c |  124 +++++++++++++++++++-----------------
 1 files changed, 65 insertions(+), 59 deletions(-)
---
diff --git a/extensions/jpeg_utils/jpeg-info.c b/extensions/jpeg_utils/jpeg-info.c
index a225382..c1b980a 100644
--- a/extensions/jpeg_utils/jpeg-info.c
+++ b/extensions/jpeg_utils/jpeg-info.c
@@ -23,15 +23,31 @@
 #include <config.h>
 #include "jpeg-info.h"
 
+static guchar
+_g_input_stream_read_byte (GInputStream  *stream,
+			   GCancellable  *cancellable,
+			   GError       **error)
+{
+	guchar v;
+
+	if (g_input_stream_read (stream, &v, 1, cancellable, error) > 0)
+		return v;
+	else
+		return 0;
+}
+
 
 static guchar
-_jpeg_read_segment_marker (GDataInputStream  *data_stream,
-			   GCancellable      *cancellable,
-			   GError           **error)
+_jpeg_read_segment_marker (GInputStream  *stream,
+			   GCancellable  *cancellable,
+			   GError       **error)
 {
 	guchar marker_id;
 
-	while ((marker_id = g_data_input_stream_read_byte (data_stream, cancellable, error)) == 0xff)
+	if (_g_input_stream_read_byte (stream, cancellable, error) != 0xff)
+		return 0x00;
+
+	while ((marker_id = _g_input_stream_read_byte (stream, cancellable, error)) == 0xff)
 		/* skip padding */;
 
 	return marker_id;
@@ -39,10 +55,10 @@ _jpeg_read_segment_marker (GDataInputStream  *data_stream,
 
 
 static gboolean
-_jpeg_skip_segment_data (GDataInputStream  *data_stream,
-			 guchar             marker_id,
-			 GCancellable      *cancellable,
-			 GError           **error)
+_jpeg_skip_segment_data (GInputStream  *stream,
+			 guchar         marker_id,
+			 GCancellable  *cancellable,
+			 GError       **error)
 {
 	if (marker_id == 0xd9)  /* EOI => end of image */
 		return FALSE;
@@ -65,17 +81,12 @@ _jpeg_skip_segment_data (GDataInputStream  *data_stream,
 
 		/* skip to the next segment */
 
-		h = g_data_input_stream_read_byte (data_stream, cancellable, error);
-		l = g_data_input_stream_read_byte (data_stream, cancellable, error);
+		h = _g_input_stream_read_byte (stream, cancellable, error);
+		l = _g_input_stream_read_byte (stream, cancellable, error);
 		segment_size = (h << 8) + l;
 
-		if (g_input_stream_skip (G_INPUT_STREAM (data_stream),
-					 segment_size - 2,
-					 cancellable,
-					 error) < 0)
-		{
+		if (g_input_stream_skip (stream, segment_size - 2, cancellable, error) < 0)
 			return FALSE;
-		}
 	}
 
 	return TRUE;
@@ -83,17 +94,17 @@ _jpeg_skip_segment_data (GDataInputStream  *data_stream,
 
 
 static gboolean
-_jpeg_skip_to_segment (GDataInputStream  *data_stream,
-		       guchar             segment_id,
-		       GCancellable      *cancellable,
-		       GError           **error)
+_jpeg_skip_to_segment (GInputStream  *stream,
+		       guchar         segment_id,
+		       GCancellable  *cancellable,
+		       GError       **error)
 {
 	guchar marker_id = 0x00;
 
-	while ((marker_id = _jpeg_read_segment_marker (data_stream, cancellable, error)) != 0x00) {
+	while ((marker_id = _jpeg_read_segment_marker (stream, cancellable, error)) != 0x00) {
 		if (marker_id == segment_id)
 			return TRUE;
-		if (! _jpeg_skip_segment_data (data_stream, marker_id, cancellable, error))
+		if (! _jpeg_skip_segment_data (stream, marker_id, cancellable, error))
 			return FALSE;
 	}
 
@@ -116,7 +127,7 @@ _jpeg_exif_orientation_from_app1_segment (guchar *in_buffer,
 	/* Following Exif data length must be at least 6 */
 
 	length = app1_segment_size;
-	if (length < 8)
+	if (length < 6)
 		return 0;
 
 	pos = 0;
@@ -261,10 +272,10 @@ _jpeg_get_image_info (GInputStream  *stream,
 		      GCancellable  *cancellable,
 		      GError       **error)
 {
-	gboolean          size_read;
-	gboolean          orientation_read;
-	GDataInputStream *data_stream;
-	guchar            marker_id;
+	gboolean size_read;
+	gboolean orientation_read;
+	int      n_marker = 0;
+	guchar   marker_id;
 
 	size_read = FALSE;
 
@@ -276,35 +287,34 @@ _jpeg_get_image_info (GInputStream  *stream,
 		/* no need to search for the orientation flag if orientation is NULL */
 		orientation_read = TRUE;
 
-	data_stream = g_data_input_stream_new (stream);
-	g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (data_stream), FALSE);
+	while ((marker_id = _jpeg_read_segment_marker (stream, cancellable, error)) != 0x00) {
+		gboolean segment_data_consumed = FALSE;
 
-	while ((marker_id = _jpeg_read_segment_marker (data_stream, cancellable, error)) != 0x00) {
-		if (marker_id == 0xc0) { /* SOF0 */
+		if ((marker_id == 0xc0) || (marker_id == 0xc2)) { /* SOF */
 			guint h, l;
 			guint size;
 
 			/* size */
 
-			h = g_data_input_stream_read_byte (data_stream, cancellable, error);
-			l = g_data_input_stream_read_byte (data_stream, cancellable, error);
+			h = _g_input_stream_read_byte (stream, cancellable, error);
+			l = _g_input_stream_read_byte (stream, cancellable, error);
 			size = (h << 8) + l;
 
 			/* data precision */
 
-			(void) g_data_input_stream_read_byte (data_stream, cancellable, error);
+			(void) _g_input_stream_read_byte (stream, cancellable, error);
 
 			/* height */
 
-			h = g_data_input_stream_read_byte (data_stream, cancellable, error);
-			l = g_data_input_stream_read_byte (data_stream, cancellable, error);
+			h = _g_input_stream_read_byte (stream, cancellable, error);
+			l = _g_input_stream_read_byte (stream, cancellable, error);
 			if (height != NULL)
 				*height = (h << 8) + l;
 
 			/* width */
 
-			h = g_data_input_stream_read_byte (data_stream, cancellable, error);
-			l = g_data_input_stream_read_byte (data_stream, cancellable, error);
+			h = _g_input_stream_read_byte (stream, cancellable, error);
+			l = _g_input_stream_read_byte (stream, cancellable, error);
 			if (width != NULL)
 				*width = (h << 8) + l;
 
@@ -312,39 +322,40 @@ _jpeg_get_image_info (GInputStream  *stream,
 
 			/* skip to the end of the segment */
 
-			if (! orientation_read)
-				g_input_stream_skip (G_INPUT_STREAM (data_stream), size - 7, cancellable, error);
+			g_input_stream_skip (stream, size - 7, cancellable, error);
+			segment_data_consumed = TRUE;
 		}
 
-		if (! orientation_read && (marker_id == 0xe1)) { /* APP1 */
+		if ((n_marker == 1) && (marker_id == 0xe1)) { /* APP1 */
 			guint   h, l;
 			gsize   size;
 			guchar *app1_segment;
 
 			/* size */
 
-			h = g_data_input_stream_read_byte (data_stream, cancellable, error);
-			l = g_data_input_stream_read_byte (data_stream, cancellable, error);
-			size = (h << 8) + l;
+			h = _g_input_stream_read_byte (stream, cancellable, error);
+			l = _g_input_stream_read_byte (stream, cancellable, error);
+			size = (h << 8) + l - 2;
 
 			app1_segment = g_new (guchar, size);
 			if (g_input_stream_read (stream, app1_segment, size, cancellable, error) > 0)
 				*orientation = _jpeg_exif_orientation_from_app1_segment (app1_segment, size);
 
 			orientation_read = TRUE;
+			segment_data_consumed = TRUE;
 
 			g_free (app1_segment);
 		}
 
-		if (size_read && orientation_read)
+		n_marker++;
+
+		if (size_read)
 			break;
 
-		if (! _jpeg_skip_segment_data (data_stream, marker_id, cancellable, error))
+		if (! segment_data_consumed && ! _jpeg_skip_segment_data (stream, marker_id, cancellable, error))
 			break;
 	}
 
-	g_object_unref (data_stream);
-
 	return size_read;
 }
 
@@ -370,22 +381,19 @@ _jpeg_exif_orientation_from_stream (GInputStream  *stream,
 				    GCancellable  *cancellable,
 				    GError       **error)
 {
-	GthTransform      orientation;
-	GDataInputStream *data_stream;
+	GthTransform   orientation;
 
 	orientation = GTH_TRANSFORM_NONE;
-	data_stream = g_data_input_stream_new (stream);
-	g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (data_stream), FALSE);
 
-	if (_jpeg_read_segment_marker (data_stream, cancellable, error) == 0xd8) {
-		if (_jpeg_skip_to_segment (data_stream, 0xe1, cancellable, error)) {
+	if (_jpeg_read_segment_marker (stream, cancellable, error) == 0xd8) {
+		if (_jpeg_skip_to_segment (stream, 0xe1, cancellable, error)) {
 			guint   h, l;
 			guint   app1_segment_size;
 			guchar *app1_segment;
 
-			h = g_data_input_stream_read_byte (data_stream, cancellable, error);
-			l = g_data_input_stream_read_byte (data_stream, cancellable, error);
-			app1_segment_size = (h << 8) + l;
+			h = _g_input_stream_read_byte (stream, cancellable, error);
+			l = _g_input_stream_read_byte (stream, cancellable, error);
+			app1_segment_size = (h << 8) + l - 2;
 
 			app1_segment = g_new (guchar, app1_segment_size);
 			if (g_input_stream_read (stream,
@@ -401,7 +409,5 @@ _jpeg_exif_orientation_from_stream (GInputStream  *stream,
 		}
 	}
 
-	g_object_unref (data_stream);
-
 	return orientation;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]