gnome-scan r727 - in trunk: . modules/gsane
- From: bersace svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-scan r727 - in trunk: . modules/gsane
- Date: Sun, 21 Dec 2008 16:36:06 +0000 (UTC)
Author: bersace
Date: Sun Dec 21 16:36:06 2008
New Revision: 727
URL: http://svn.gnome.org/viewvc/gnome-scan?rev=727&view=rev
Log:
Added three-pass nbit data support.
Modified:
trunk/ChangeLog
trunk/modules/gsane/gsane-processor.c
Modified: trunk/modules/gsane/gsane-processor.c
==============================================================================
--- trunk/modules/gsane/gsane-processor.c (original)
+++ trunk/modules/gsane/gsane-processor.c Sun Dec 21 16:36:06 2008
@@ -41,6 +41,7 @@
volatile guint bytes_processed;
/* total number of frame to acquire to get the entire image */
guint frame_count;
+ /* number of sample in frame */
guint sample_count;
/* offset of a sample in bytes for three-pass acquisition */
guint sample_offset;
@@ -161,14 +162,15 @@
src_pos = i * self->priv->bytes_per_pixel / self->priv->sample_count;
/* retrieve bytes containing sample value */
memcpy(&value, buf+src_pos, self->priv->sample_stride);
- /* compute the offset of the samples bits inside the sample stride */
- offset = (8 * self->priv->sample_stride) - ((i * self->priv->params->depth) - (src_pos * 8)) - 1;
+ /* At which bit from right of value start the sample. */
+ offset = (i * self->priv->params->depth) - (src_pos * 8);
/* align sample bits to the right */
value = value >> offset;
/* apply sample patter to get sample value */
value = value & self->priv->sample_pattern;
/* compute target value */
- value = self->priv->max_target_sample_value * (value / self->priv->max_sample_value);
+ value = (gdouble)self->priv->max_target_sample_value * ((gdouble)value / (gdouble)self->priv->max_sample_value);
+
/* get the address of the first byte set. */
src = (guchar*)(&value);
#if G_BYTE_ORDER == G_BIG_ENDIAN
@@ -183,7 +185,6 @@
gegl_buffer_set(self->priv->buffer, &roi, self->priv->format, buf8, GEGL_AUTO_ROWSTRIDE);
g_free(buf8);
}
-
static void
gsane_processor_process_three_pass_1bit(GSaneProcessor *self, guchar *buf, guint buf_len)
{
@@ -225,6 +226,43 @@
g_free(buf3);
}
+
+static void
+gsane_processor_process_three_pass_nbit(GSaneProcessor *self, guchar *buf, guint buf_len)
+{
+ GeglRectangle roi = self->priv->rect;
+ guint32 value = 0;
+ guchar *src, *dest, *buf8 = g_new0(guchar, self->priv->pixels_in_buf * self->priv->sample_stride * self->priv->frame_count);
+ guint i, offset, src_pos;
+ gegl_buffer_get(self->priv->buffer, 1.0, &roi, self->priv->format, buf8, GEGL_AUTO_ROWSTRIDE);
+ for (i = 0; i < self->priv->pixels_in_buf; i++) {
+ /* compute the address of the first byte container sample value */
+ src_pos = i* self->priv->bytes_per_pixel;
+ /* retrieve bytes containing sample value */
+ memcpy(&value, buf + src_pos, self->priv->sample_stride);
+ /* compute the offset of the samples bits inside the sample stride */
+ offset = (8 * self->priv->sample_stride) - ((i * self->priv->params->depth) - (src_pos * 8)) - 1;
+ /* align sample bits to the right */
+ value = value >> offset;
+ /* apply sample patter to get sample value */
+ value = value & self->priv->sample_pattern;
+ /* compute target value */
+ value = self->priv->max_target_sample_value * (value / self->priv->max_sample_value);
+ /* get the address of the first byte set. */
+ src = (guchar*)(&value);
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+ src = src + (sizeof(value) - self->priv->sample_stride);
+#endif
+ /* compute the first byte target address */
+ dest = buf8 + i * self->priv->frame_count * self->priv->sample_stride + self->priv->sample_offset;
+ /* save */
+ memcpy(dest, src, self->priv->sample_stride);
+ }
+ /* send */
+ gegl_buffer_set(self->priv->buffer, &roi, self->priv->format, buf8, GEGL_AUTO_ROWSTRIDE);
+ g_free(buf8);
+}
+
static GSaneProcessorFunc
gsane_processor_get_func(GSaneProcessor *self)
{
@@ -247,7 +285,7 @@
else if (self->priv->params->depth == 1)
func = gsane_processor_process_three_pass_1bit;
else
- g_warning("Unsupported %dbit three-pass frame format", self->priv->params->depth);
+ func = gsane_processor_process_three_pass_nbit;
break;
default:
g_warning("Unsupported SANE frame format.");
@@ -308,14 +346,34 @@
case SANE_FRAME_RED:
return 0;
case SANE_FRAME_GREEN:
- return self->priv->pixel_stride;
+ return self->priv->sample_stride;
case SANE_FRAME_BLUE:
- return 2 * self->priv->pixel_stride;
+ return 2 * self->priv->sample_stride;
default:
return 0;
}
}
+static guint
+gsane_processor_get_sample_count(GSaneProcessor *self)
+{
+ switch(self->priv->params->format) {
+ case SANE_FRAME_RGB:
+ return 3;
+ case SANE_FRAME_GRAY:
+ case SANE_FRAME_RED:
+ case SANE_FRAME_GREEN:
+ case SANE_FRAME_BLUE:
+ return 1;
+ break;
+ default:
+ g_warning("Unsupported SANE frame format.");
+ break;
+ }
+
+ return 0;
+}
+
/* Initialize acquisition of one image. Returns the buffer initialized
with right format and extent. */
GeglBuffer*
@@ -331,11 +389,12 @@
};
self->priv->params = params;
+ /* computes values used by various processor func */
self->priv->frame_count = frame_count;
- self->priv->bytes_per_pixel = (gdouble)params->bytes_per_line / (gdouble)params->pixels_per_line;
+ self->priv->sample_count = gsane_processor_get_sample_count(self);
+ self->priv->bits_per_pixel = params->depth * self->priv->sample_count;
+ self->priv->bytes_per_pixel = (gdouble) self->priv->bits_per_pixel / 8.;
self->priv->pixel_stride = floor(self->priv->bytes_per_pixel) + (self->priv->bytes_per_pixel > (gdouble)((guint) self->priv->bytes_per_pixel) ? 1 : 0);
- self->priv->bits_per_pixel = 8 * self->priv->bytes_per_pixel;
- self->priv->sample_count = self->priv->bits_per_pixel / self->priv->params->depth;
self->priv->max_sample_value = (0xFFFFFFFF) >> (32 - self->priv->params->depth);
self->priv->pixel_pattern = (0xFFFFFFFF) >> (32 - self->priv->bits_per_pixel);
self->priv->sample_pattern = (0xFFFFFFFF) >> (32 - self->priv->params->depth);
@@ -346,8 +405,8 @@
self->priv->format = gsane_processor_get_babl_format(self);
g_return_val_if_fail(self->priv->format, NULL);
- self->priv->sample_stride = self->priv->format->format.bytes_per_pixel / self->priv->sample_count;
- self->priv->max_target_sample_value= (0xFFFFFFFF) >> (32 - self->priv->format->format.bytes_per_pixel / self->priv->sample_count * 8);
+ self->priv->sample_stride = self->priv->format->format.bytes_per_pixel / MAX(self->priv->sample_count, self->priv->frame_count);
+ self->priv->max_target_sample_value= (0xFFFFFFFF) >> (32 - self->priv->sample_stride * 8);
self->priv->buffer = gegl_buffer_new(&extent, self->priv->format);
return self->priv->buffer;
@@ -373,7 +432,7 @@
self->priv->rect.y = self->priv->bytes_processed / self->priv->params->bytes_per_line;
self->priv->rect.x = self->priv->bytes_processed % self->priv->params->bytes_per_line;
guint pixel_to_end_of_line = self->priv->params->pixels_per_line - self->priv->rect.x;
- self->priv->pixels_in_buf = (gdouble)buf_len / self->priv->bytes_per_pixel;
+ self->priv->pixels_in_buf = (gdouble)buf_len / self->priv->params->bytes_per_line * self->priv->params->pixels_per_line;
self->priv->rect.width = MIN (self->priv->pixels_in_buf - self->priv->rect.x, pixel_to_end_of_line);
/* compute the height of the rect and determine whether buf is
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]