summaryrefslogtreecommitdiff
path: root/src/scanner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scanner.c')
-rw-r--r--src/scanner.c70
1 files changed, 64 insertions, 6 deletions
diff --git a/src/scanner.c b/src/scanner.c
index 8383f9f..f4eb08f 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -1160,7 +1160,7 @@ do_get_option (Scanner *scanner)
}
else if (strcmp (option->name, "three-pass") == 0) {
set_bool_option (scanner->priv->handle, option, option_index, FALSE, NULL);
- }
+ }
else if (strcmp (option->name, "test-picture") == 0) {
set_string_option (scanner->priv->handle, option, option_index, "Color pattern", NULL);
}
@@ -1255,6 +1255,11 @@ do_get_parameters (Scanner *scanner)
info->width = scanner->priv->parameters.pixels_per_line;
info->height = scanner->priv->parameters.lines;
info->depth = scanner->priv->parameters.depth;
+ /* Reduce bit depth if requested lower than received */
+ // FIXME: This a hack and only works on 8 bit gray to 2 bit gray
+ if (scanner->priv->parameters.depth == 8 && scanner->priv->parameters.format == SANE_FRAME_GRAY && job->depth == 2 && job->scan_mode == SCAN_MODE_GRAY)
+ info->depth = job->depth;
+ info->n_channels = scanner->priv->parameters.format == SANE_FRAME_GRAY ? 1 : 3;
info->dpi = job->dpi; // FIXME: This is the requested DPI, not the actual DPI
info->device = g_strdup (scanner->priv->current_device);
@@ -1308,10 +1313,13 @@ do_complete_page (Scanner *scanner)
static void
do_read (Scanner *scanner)
{
+ ScanJob *job;
SANE_Status status;
SANE_Int n_to_read, n_read;
gboolean full_read = FALSE;
+ job = (ScanJob *) scanner->priv->job_queue->data;
+
/* Read as many bytes as we expect */
n_to_read = scanner->priv->buffer_size - scanner->priv->n_used;
@@ -1351,19 +1359,19 @@ do_read (Scanner *scanner)
line = g_malloc(sizeof(ScanLine));
switch (scanner->priv->parameters.format) {
case SANE_FRAME_GRAY:
- line->format = LINE_GRAY;
+ line->channel = 0;
break;
case SANE_FRAME_RGB:
- line->format = LINE_RGB;
+ line->channel = -1;
break;
case SANE_FRAME_RED:
- line->format = LINE_RED;
+ line->channel = 0;
break;
case SANE_FRAME_GREEN:
- line->format = LINE_GREEN;
+ line->channel = 1;
break;
case SANE_FRAME_BLUE:
- line->format = LINE_BLUE;
+ line->channel = 2;
break;
}
line->width = scanner->priv->parameters.pixels_per_line;
@@ -1387,6 +1395,56 @@ do_read (Scanner *scanner)
scanner->priv->buffer[i] = line->data[i + (line->n_lines * line->data_length)];
scanner->priv->n_used++;
}
+
+ /* Reduce bit depth if requested lower than received */
+ // FIXME: This a hack and only works on 8 bit gray to 2 bit gray
+ if (scanner->priv->parameters.depth == 8 && scanner->priv->parameters.format == SANE_FRAME_GRAY &&
+ job->depth == 2 && job->scan_mode == SCAN_MODE_GRAY) {
+ gint block_shift = 6;
+ guchar block = 0;
+ guchar *write_ptr = line->data;
+
+ for (i = 0; i < line->n_lines; i++) {
+ guchar *in_line = line->data + i * line->data_length;
+ gint x;
+
+ for (x = 0; x < line->width; x++) {
+ guchar *p = in_line + x;
+ guchar sample;
+
+ if (p[0] >= 192)
+ sample = 3;
+ else if (p[0] >= 128)
+ sample = 2;
+ else if (p[0] >= 64)
+ sample = 1;
+ else
+ sample = 0;
+
+ block |= sample << block_shift;
+ if (block_shift == 0) {
+ *write_ptr = block;
+ write_ptr++;
+ block = 0;
+ block_shift = 6;
+ }
+ else {
+ block_shift -= 2;
+ }
+ }
+
+ /* Finish each line on a byte boundary */
+ if (block_shift != 6) {
+ *write_ptr = block;
+ write_ptr++;
+ block = 0;
+ block_shift = 6;
+ }
+ }
+
+ line->data_length = (line->width * 2 + 7) / 8;
+ }
+
emit_signal (scanner, GOT_LINE, line);
}
}