gnome-scan r719 - in trunk: . modules/gsane



Author: bersace
Date: Sat Dec 20 17:48:49 2008
New Revision: 719
URL: http://svn.gnome.org/viewvc/gnome-scan?rev=719&view=rev

Log:
Added three-pass acquisition support.

Modified:
   trunk/ChangeLog
   trunk/modules/gsane/gsane-processor.c
   trunk/modules/gsane/gsane-processor.h
   trunk/modules/gsane/gsane-scanner.c

Modified: trunk/modules/gsane/gsane-processor.c
==============================================================================
--- trunk/modules/gsane/gsane-processor.c	(original)
+++ trunk/modules/gsane/gsane-processor.c	Sat Dec 20 17:48:49 2008
@@ -28,6 +28,10 @@
 	gdouble bytes_per_pixel;
 	/* total bytes read*/
 	volatile guint bytes_read;
+	/* total number of frame to acquire to get the entire image */
+	guint frame_count;
+	/* offset of a sample in bytes */
+	guint sample_offset;
 	/* output format of processor */
 	Babl* format;
 	GeglBuffer *buffer;
@@ -100,6 +104,34 @@
 	gegl_buffer_set (self->priv->buffer, &roi, self->priv->format, buf, GEGL_AUTO_ROWSTRIDE);
 }
 
+static guint
+gsane_processor_get_sample_offset(GSaneProcessor *self)
+{
+	switch(self->priv->params->format) {
+	case SANE_FRAME_RED:
+		return 0;
+	case SANE_FRAME_GREEN:
+		return 1;
+	case SANE_FRAME_BLUE:
+		return 2;
+	default:
+		return 0;
+	}
+}
+
+static void
+gsane_processor_process_three_pass_8bit(GSaneProcessor *self, guchar *buf, guint buf_len)
+{
+	GeglRectangle roi = self->priv->rect;
+	guchar *buf3 = g_new0(guchar, 3*buf_len);
+	guint i;
+	gegl_buffer_get(self->priv->buffer, 1.0, &roi, self->priv->format, buf3, GEGL_AUTO_ROWSTRIDE);
+	for (i = 0; i < buf_len; i++)
+		buf3[3*i+self->priv->sample_offset] = buf[i];
+	gegl_buffer_set(self->priv->buffer, &roi, self->priv->format, buf3, GEGL_AUTO_ROWSTRIDE);
+	g_free(buf3);
+}
+
 static GSaneProcessorFunc
 gsane_processor_get_func(GSaneProcessor *self)
 {
@@ -107,11 +139,19 @@
 	switch(self->priv->params->format) {
 	case SANE_FRAME_RGB:
 	case SANE_FRAME_GRAY:
-		if (self->priv->params->depth/8)
+		if (self->priv->params->depth%8 == 0)
 			func = gsane_processor_process_8bit;
 		else
 			g_warning("Unsupported %dbit frame format.", self->priv->params->depth);
 		break;
+	case SANE_FRAME_RED:
+	case SANE_FRAME_GREEN:
+	case SANE_FRAME_BLUE:
+		if (self->priv->params->depth%8 == 0)
+			func = gsane_processor_process_three_pass_8bit;
+		else
+			g_warning("Unsupported %dbit three-pass frame format", self->priv->params->depth);
+		break;
 	default:
 		g_warning("Unsupported SANE frame format.");
 		break;
@@ -120,7 +160,7 @@
 }
 
 GeglBuffer*
-gsane_processor_prepare(GSaneProcessor *self, SANE_Parameters* params)
+gsane_processor_prepare_image(GSaneProcessor *self, SANE_Parameters* params, guint frame_count)
 {
 	GeglRectangle extent = {
 		.x = 0, .y = 0,
@@ -129,6 +169,7 @@
 	};
 
 	self->priv->params = params;
+	self->priv->frame_count = frame_count;
 	self->priv->bytes_per_pixel = (gdouble)params->bytes_per_line/(gdouble)params->pixels_per_line;
 	self->priv->process = gsane_processor_get_func(self);
 	g_return_val_if_fail(self->priv->process, NULL);
@@ -140,6 +181,34 @@
 }
 
 void
+gsane_processor_prepare_frame(GSaneProcessor *self, SANE_Parameters* params)
+{
+	self->priv->params = params;
+	self->priv->bytes_read = 0;
+	self->priv->sample_offset = gsane_processor_get_sample_offset(self);
+	switch(params->format) {
+	case SANE_FRAME_GRAY:
+		g_debug("Processing GRAY frame format");
+		break;
+	case SANE_FRAME_RGB:
+		g_debug("Processing RGB frame format");
+		break;
+	case SANE_FRAME_RED:
+		g_debug("Processing RED frame format");
+		break;
+	case SANE_FRAME_GREEN:
+		g_debug("Processing GREEN frame format");
+		break;
+	case SANE_FRAME_BLUE:
+		g_debug("Processing BLUE frame format");
+		break;
+	default:
+		g_debug("Unknown frame format");
+		break;
+	}
+}
+
+void
 gsane_processor_process(GSaneProcessor *self, guchar *buf, guint buf_len)
 {
 	g_return_if_fail(self->priv->process);

Modified: trunk/modules/gsane/gsane-processor.h
==============================================================================
--- trunk/modules/gsane/gsane-processor.h	(original)
+++ trunk/modules/gsane/gsane-processor.h	Sat Dec 20 17:48:49 2008
@@ -35,7 +35,8 @@
 };
 
 void gsane_processor_init(GSaneProcessor *self);
-GeglBuffer* gsane_processor_prepare(GSaneProcessor *self, SANE_Parameters *params);
+GeglBuffer* gsane_processor_prepare_image(GSaneProcessor *self, SANE_Parameters *params, guint frame_count);
+void gsane_processor_prepare_frame(GSaneProcessor *self, SANE_Parameters *params);
 void gsane_processor_process(GSaneProcessor *self, guchar* buf, guint buf_len);
 void gsane_processor_destroy(GSaneProcessor*self);
 

Modified: trunk/modules/gsane/gsane-scanner.c
==============================================================================
--- trunk/modules/gsane/gsane-scanner.c	(original)
+++ trunk/modules/gsane/gsane-scanner.c	Sat Dec 20 17:48:49 2008
@@ -49,10 +49,6 @@
 	guint image_count;
 	/* SANE frame paramters */
 	SANE_Parameters params;
-	/* total number of frame to acquire to get the entire image */
-	guint frame_count;
-	/* number of frame acquired */
-	guint frame_acquired;
 	guint bytes_per_pixel;
 	/* total bytes read*/
 	volatile guint bytes_read;
@@ -213,6 +209,34 @@
 	return NULL;
 }
 
+static void
+gsane_scanner_start_scan(GnomeScanNode *node)
+{
+	GSaneScanner *self = GSANE_SCANNER(node);
+	self->priv->image_count = 0;
+}
+
+static gboolean gsane_scanner_start_frame(GSaneScanner *self)
+{
+	SANE_Status status;
+
+	sane_cancel(self->priv->handle);
+
+	status = sane_start(self->priv->handle);
+	if (!gsane_scanner_check_sane_status(self, "sane_start", status))
+		return FALSE;
+
+	status = sane_get_parameters(self->priv->handle, &self->priv->params);
+	if (!gsane_scanner_check_sane_status(self, "sane_get_parameters", status))
+		return FALSE;
+
+	gsane_processor_prepare_frame(&self->priv->processor, &self->priv->params);
+
+	g_debug("New frame started");
+
+	return TRUE;
+}
+
 static guint
 gsane_scanner_get_frame_count(GSaneScanner *self)
 {
@@ -229,38 +253,27 @@
 	}
 }
 
-static void
-gsane_scanner_start_scan(GnomeScanNode *node)
-{
-	GSaneScanner *self = GSANE_SCANNER(node);
-	self->priv->image_count = 0;
-}
-
 static gboolean
 gsane_scanner_start_image(GnomeScanNode *node)
 {
 	GSaneScanner *self = GSANE_SCANNER(node);
 	GeglBuffer *buffer;
+	guint frame_count;
 
 	if (self->priv->image_count > 0 && !self->priv->is_adf_selected)
 		return FALSE;
 
-	SANE_Status status = sane_start(self->priv->handle);
-	if (!gsane_scanner_check_sane_status(self, "sane_start", status))
-		return FALSE;
-
-	status = sane_get_parameters(self->priv->handle, &self->priv->params);
-	if (!gsane_scanner_check_sane_status(self, "sane_get_parameters", status))
+	if (!gsane_scanner_start_frame(self))
 		return FALSE;
 
-	self->priv->frame_count = gsane_scanner_get_frame_count(self);
-	self->priv->frame_acquired = 0;
+	frame_count = gsane_scanner_get_frame_count(self);
 	self->priv->bytes_read = 0;
 	self->priv->bytes_per_pixel = self->priv->params.bytes_per_line/self->priv->params.pixels_per_line;
-	self->priv->total_bytes_count = self->priv->params.bytes_per_line * self->priv->params.lines * self->priv->frame_count;
+	self->priv->total_bytes_count = self->priv->params.pixels_per_line * self->priv->params.lines * frame_count;
 
-	buffer = gsane_processor_prepare(&self->priv->processor, &self->priv->params);
+	buffer = gsane_processor_prepare_image(&self->priv->processor, &self->priv->params, frame_count);
 	gnome_scan_scanner_set_buffer((GnomeScanScanner*)self, buffer);
+
 	return TRUE;
 }
 
@@ -277,7 +290,15 @@
 	status = sane_read (self->priv->handle, buf, chunk_len, &read_len);
 	if (status != SANE_STATUS_GOOD) {
 		g_debug("%s", sane_strstatus(status));
-		return FALSE;
+		if (status == SANE_STATUS_EOF) {
+			if (!self->priv->params.last_frame)
+				/* start next frame */
+				return gsane_scanner_start_frame(self);
+			else
+				return FALSE;
+		}
+		else
+			return FALSE;
 	}
 
 	self->priv->bytes_read += read_len;



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