kopia lustrzana https://gitlab.com/sane-project/backends
1 bit B/W lineart for pixma_mp150 and pixma_810 subdrivers
rodzic
bd379a59aa
commit
974ee17cf4
|
@ -1,3 +1,8 @@
|
||||||
|
2012-02-03 Rolf Bensch <rolf at bensch hyphen online dot de>
|
||||||
|
* backend/pixma.[ch], backend/pixma_common.[ch],
|
||||||
|
backend/pixma_sane_options.[ch], backend/pixma_mp{150,810}.c:
|
||||||
|
1 bit B/W lineart for pixma_mp150 and pixma_810 subdrivers.
|
||||||
|
|
||||||
2012-02-03 Rolf Bensch <rolf at bensch hyphen online dot de>
|
2012-02-03 Rolf Bensch <rolf at bensch hyphen online dot de>
|
||||||
* backend/pixma.h: set PIXMA_VERSION_{MAJOR,MINOR,BUILD} to 0.16.3.
|
* backend/pixma.h: set PIXMA_VERSION_{MAJOR,MINOR,BUILD} to 0.16.3.
|
||||||
|
|
||||||
|
|
121
backend/pixma.c
121
backend/pixma.c
|
@ -84,8 +84,10 @@
|
||||||
#define OVAL(opt) OPT_IN_CTX[opt].val
|
#define OVAL(opt) OPT_IN_CTX[opt].val
|
||||||
#define AUTO_GAMMA 2.2
|
#define AUTO_GAMMA 2.2
|
||||||
|
|
||||||
#include "pixma_sane_options.h" /* generated by gen_options.py */
|
/* pixma_sane_options.h generated by
|
||||||
|
* scripts/pixma_gen_options.py h < pixma.c > pixma_sane_options.h
|
||||||
|
* *and* formatted */
|
||||||
|
#include "pixma_sane_options.h"
|
||||||
|
|
||||||
typedef struct pixma_sane_t
|
typedef struct pixma_sane_t
|
||||||
{
|
{
|
||||||
|
@ -103,6 +105,7 @@ typedef struct pixma_sane_t
|
||||||
SANE_Range xrange, yrange;
|
SANE_Range xrange, yrange;
|
||||||
SANE_Word dpi_list[9]; /* up to 9600 dpi */
|
SANE_Word dpi_list[9]; /* up to 9600 dpi */
|
||||||
SANE_String_Const mode_list[4];
|
SANE_String_Const mode_list[4];
|
||||||
|
pixma_scan_mode_t mode_map[4];
|
||||||
uint8_t gamma_table[4096];
|
uint8_t gamma_table[4096];
|
||||||
SANE_String_Const source_list[4];
|
SANE_String_Const source_list[4];
|
||||||
pixma_paper_source_t source_map[4];
|
pixma_paper_source_t source_map[4];
|
||||||
|
@ -324,6 +327,43 @@ clamp_value (pixma_sane_t * ss, SANE_Int n, void *v, SANE_Int * info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* create dynamic mode_list
|
||||||
|
* ss: scanner device
|
||||||
|
* tpu = 0: flatbed or ADF mode
|
||||||
|
* 1 bit lineart, 8 bit grayscale and 24 bit color scans
|
||||||
|
* tpu = 1: TPU mode
|
||||||
|
* 16 bit grayscale and 48 bit color scans */
|
||||||
|
static void
|
||||||
|
create_mode_list (pixma_sane_t * ss, SANE_Bool tpu)
|
||||||
|
{
|
||||||
|
const pixma_config_t *cfg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cfg = pixma_get_config (ss->s);
|
||||||
|
|
||||||
|
/* setup available mode. */
|
||||||
|
i = 0;
|
||||||
|
ss->mode_list[i] = SANE_VALUE_SCAN_MODE_COLOR;
|
||||||
|
ss->mode_map[i] = PIXMA_SCAN_MODE_COLOR;
|
||||||
|
i++;
|
||||||
|
if (cfg->cap & PIXMA_CAP_GRAY)
|
||||||
|
{
|
||||||
|
ss->mode_list[i] = SANE_VALUE_SCAN_MODE_GRAY;
|
||||||
|
ss->mode_map[i] = PIXMA_SCAN_MODE_GRAY;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tpu && cfg->cap & PIXMA_CAP_LINEART)
|
||||||
|
{
|
||||||
|
ss->mode_list[i] = SANE_VALUE_SCAN_MODE_LINEART;
|
||||||
|
ss->mode_map[i] = PIXMA_SCAN_MODE_LINEART;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
/* terminate mode_list and mode_map */
|
||||||
|
ss->mode_list[i] = 0;
|
||||||
|
ss->mode_map[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* create ss->dpi_list
|
/* create ss->dpi_list
|
||||||
* ss: scanner device
|
* ss: scanner device
|
||||||
* ext = 0: min = 75 dpi; max = cfg->xdpi
|
* ext = 0: min = 75 dpi; max = cfg->xdpi
|
||||||
|
@ -533,6 +573,8 @@ control_option (pixma_sane_t * ss, SANE_Int n,
|
||||||
|
|
||||||
cfg = pixma_get_config (ss->s);
|
cfg = pixma_get_config (ss->s);
|
||||||
|
|
||||||
|
/* PDBG (pixma_dbg (4, "*control_option***** n = %u, a = %u\n", n, a)); */
|
||||||
|
|
||||||
result = SANE_STATUS_UNSUPPORTED;
|
result = SANE_STATUS_UNSUPPORTED;
|
||||||
switch (n)
|
switch (n)
|
||||||
{
|
{
|
||||||
|
@ -598,22 +640,46 @@ control_option (pixma_sane_t * ss, SANE_Int n,
|
||||||
*info |= SANE_INFO_RELOAD_OPTIONS;
|
*info |= SANE_INFO_RELOAD_OPTIONS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case opt_mode:
|
||||||
|
if (a == SANE_ACTION_SET_VALUE || a == SANE_ACTION_SET_AUTO)
|
||||||
|
{
|
||||||
|
if (ss->mode_map[OVAL (opt_mode).w] == PIXMA_SCAN_MODE_LINEART)
|
||||||
|
{
|
||||||
|
enable_option (ss, opt_threshold, SANE_TRUE);
|
||||||
|
enable_option (ss, opt_custom_gamma, SANE_FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enable_option (ss, opt_custom_gamma, SANE_TRUE);
|
||||||
|
enable_option (ss, opt_threshold, SANE_FALSE);
|
||||||
|
}
|
||||||
|
*info |= SANE_INFO_RELOAD_OPTIONS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case opt_source:
|
case opt_source:
|
||||||
if (cfg->cap & (PIXMA_CAP_ADF|PIXMA_CAP_ADFDUP|PIXMA_CAP_TPU)
|
if (cfg->cap & (PIXMA_CAP_ADF|PIXMA_CAP_ADFDUP|PIXMA_CAP_TPU)
|
||||||
&& (a == SANE_ACTION_SET_VALUE || a == SANE_ACTION_SET_AUTO))
|
&& (a == SANE_ACTION_SET_VALUE || a == SANE_ACTION_SET_AUTO))
|
||||||
{ /* new source selected: flatbed, ADF, TPU, ... */
|
{ /* new source selected: flatbed, ADF, TPU, ... */
|
||||||
/* to avoid fatal errors, select 600 dpi for dpi_list */
|
/* to avoid fatal errors, select 600 dpi
|
||||||
|
* and first entry of dynamic mode_list
|
||||||
|
* available identifiers are unknown here */
|
||||||
OVAL (opt_resolution).w = 600;
|
OVAL (opt_resolution).w = 600;
|
||||||
if (ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_TPU
|
OVAL (opt_mode).w = 0;
|
||||||
|| ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_ADF
|
/* recreate dynamic lists */
|
||||||
|
if (ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_TPU)
|
||||||
|
{ /* TPU mode */
|
||||||
|
create_mode_list (ss, SANE_TRUE);
|
||||||
|
create_dpi_list (ss, SANE_TRUE);
|
||||||
|
}
|
||||||
|
else if (ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_ADF
|
||||||
|| ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_ADFDUP)
|
|| ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_ADFDUP)
|
||||||
{
|
{ /* ADF mode */
|
||||||
/* create dpi_list for ADF/TPU mode */
|
create_mode_list (ss, SANE_FALSE);
|
||||||
create_dpi_list (ss, SANE_TRUE);
|
create_dpi_list (ss, SANE_TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ /* flatbed mode */
|
||||||
/* create dpi_list for flatbed mode */
|
create_mode_list (ss, SANE_FALSE);
|
||||||
create_dpi_list (ss, SANE_FALSE);
|
create_dpi_list (ss, SANE_FALSE);
|
||||||
}
|
}
|
||||||
*info |= SANE_INFO_RELOAD_OPTIONS;
|
*info |= SANE_INFO_RELOAD_OPTIONS;
|
||||||
|
@ -680,7 +746,9 @@ calc_scan_param (pixma_sane_t * ss, pixma_scan_param_t * sp)
|
||||||
|
|
||||||
sp->gamma_table = (OVAL (opt_custom_gamma).b) ? ss->gamma_table : NULL;
|
sp->gamma_table = (OVAL (opt_custom_gamma).b) ? ss->gamma_table : NULL;
|
||||||
sp->source = ss->source_map[OVAL (opt_source).w];
|
sp->source = ss->source_map[OVAL (opt_source).w];
|
||||||
|
sp->mode = ss->mode_map[OVAL (opt_mode).w];
|
||||||
sp->adf_pageid = ss->page_count;
|
sp->adf_pageid = ss->page_count;
|
||||||
|
sp->threshold = OVAL (opt_threshold).w;
|
||||||
|
|
||||||
error = pixma_check_scan_param (ss->s, sp);
|
error = pixma_check_scan_param (ss->s, sp);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
|
@ -715,16 +783,7 @@ init_option_descriptors (pixma_sane_t * ss)
|
||||||
* because the whole pixma_sane_t was cleared during allocation. */
|
* because the whole pixma_sane_t was cleared during allocation. */
|
||||||
|
|
||||||
/* setup available mode. */
|
/* setup available mode. */
|
||||||
ss->mode_list[0] = SANE_VALUE_SCAN_MODE_COLOR;
|
create_mode_list (ss, SANE_FALSE);
|
||||||
if (cfg->cap & PIXMA_CAP_GRAY)
|
|
||||||
{
|
|
||||||
ss->mode_list[1] = SANE_VALUE_SCAN_MODE_GRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg->cap & PIXMA_CAP_LINEART)
|
|
||||||
{
|
|
||||||
ss->mode_list[2] = SANE_VALUE_SCAN_MODE_LINEART;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setup paper source */
|
/* setup paper source */
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -1393,7 +1452,9 @@ sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
|
||||||
return ss->last_read_status;
|
return ss->last_read_status;
|
||||||
|
|
||||||
status = SANE_STATUS_GOOD;
|
status = SANE_STATUS_GOOD;
|
||||||
if ((ss->sp.line_size - ss->output_line_size) == 0)
|
/* CCD scanners use software lineart
|
||||||
|
* the scanner must scan 24 bit color for one bit lineart */
|
||||||
|
if ((ss->sp.line_size - ((ss->sp.software_lineart == 1) ? (ss->output_line_size * 8) : ss->output_line_size)) == 0)
|
||||||
{
|
{
|
||||||
status = read_image (ss, buf, maxlen, &sum);
|
status = read_image (ss, buf, maxlen, &sum);
|
||||||
}
|
}
|
||||||
|
@ -1401,6 +1462,7 @@ sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
|
||||||
{
|
{
|
||||||
/* FIXME: Because there is no frontend that can cope with padding at
|
/* FIXME: Because there is no frontend that can cope with padding at
|
||||||
the end of line, we've to remove it here in the backend! */
|
the end of line, we've to remove it here in the backend! */
|
||||||
|
PDBG (pixma_dbg (1, "*sane_read***** Warning: padding may cause incomplete scan results\n"));
|
||||||
sum = 0;
|
sum = 0;
|
||||||
while (sum < maxlen)
|
while (sum < maxlen)
|
||||||
{
|
{
|
||||||
|
@ -1513,8 +1575,8 @@ type int resolution
|
||||||
info reload_params
|
info reload_params
|
||||||
|
|
||||||
type string mode[10]
|
type string mode[10]
|
||||||
default Color
|
|
||||||
constraint @string_list = ss->mode_list
|
constraint @string_list = ss->mode_list
|
||||||
|
default @s = SANE_I18N(ss->mode_list[0])
|
||||||
title @SANE_TITLE_SCAN_MODE
|
title @SANE_TITLE_SCAN_MODE
|
||||||
desc @SANE_DESC_SCAN_MODE
|
desc @SANE_DESC_SCAN_MODE
|
||||||
cap soft_select soft_detect automatic
|
cap soft_select soft_detect automatic
|
||||||
|
@ -1607,7 +1669,22 @@ type int button-2
|
||||||
title Button 2
|
title Button 2
|
||||||
cap soft_select soft_detect advanced
|
cap soft_select soft_detect advanced
|
||||||
|
|
||||||
|
rem -------------------------------------------
|
||||||
|
type group
|
||||||
|
title Extras
|
||||||
|
|
||||||
|
type int threshold
|
||||||
|
unit PERCENT
|
||||||
|
default 50
|
||||||
|
title @SANE_TITLE_THRESHOLD
|
||||||
|
desc @SANE_DESC_THRESHOLD
|
||||||
|
cap soft_select soft_detect automatic inactive
|
||||||
|
|
||||||
rem -------------------------------------------
|
rem -------------------------------------------
|
||||||
END SANE_Option_Descriptor
|
END SANE_Option_Descriptor
|
||||||
*/
|
*/
|
||||||
#include "pixma_sane_options.c" /* generated by gen_options.py */
|
|
||||||
|
/* pixma_sane_options.c generated by
|
||||||
|
* scripts/pixma_gen_options.py < pixma.c > pixma_sane_options.c
|
||||||
|
* *and* formatted */
|
||||||
|
#include "pixma_sane_options.c"
|
||||||
|
|
|
@ -198,6 +198,16 @@ typedef enum pixma_paper_source_t
|
||||||
PIXMA_SOURCE_ADFDUP /* duplex */
|
PIXMA_SOURCE_ADFDUP /* duplex */
|
||||||
} pixma_paper_source_t;
|
} pixma_paper_source_t;
|
||||||
|
|
||||||
|
/** Scan modes */
|
||||||
|
typedef enum pixma_scan_mode_t
|
||||||
|
{
|
||||||
|
/* standard scan modes */
|
||||||
|
PIXMA_SCAN_MODE_COLOR,
|
||||||
|
PIXMA_SCAN_MODE_GRAY,
|
||||||
|
/* 1 bit lineart scan mode */
|
||||||
|
PIXMA_SCAN_MODE_LINEART
|
||||||
|
} pixma_scan_mode_t;
|
||||||
|
|
||||||
typedef enum pixma_hardware_status_t
|
typedef enum pixma_hardware_status_t
|
||||||
{
|
{
|
||||||
PIXMA_HARDWARE_OK,
|
PIXMA_HARDWARE_OK,
|
||||||
|
@ -251,10 +261,15 @@ struct pixma_scan_param_t
|
||||||
* This field will be set by pixma_check_scan_param(). */
|
* This field will be set by pixma_check_scan_param(). */
|
||||||
uint64_t image_size;
|
uint64_t image_size;
|
||||||
|
|
||||||
/** Channels per pixel. 1 = grayscale, 3 = color */
|
/** Channels per pixel. 1 = grayscale and lineart, 3 = color */
|
||||||
unsigned channels;
|
unsigned channels;
|
||||||
|
|
||||||
/** Bits per channels. 0 = default. Currently not used. */
|
/** Bits per channels.
|
||||||
|
* 1 = 1 bit B/W lineart (flatbed)
|
||||||
|
* 8 = 8 bit grayscale,
|
||||||
|
* 24 bit color (both flatbed)
|
||||||
|
* 16 = 16 bit grayscale (TPU, flatbed not implemeted),
|
||||||
|
* 48 bit color (TPU, flatbed not implemented) */
|
||||||
unsigned depth;
|
unsigned depth;
|
||||||
|
|
||||||
/*@{ */
|
/*@{ */
|
||||||
|
@ -277,6 +292,15 @@ struct pixma_scan_param_t
|
||||||
* Currently only used in pixma_mp810.c sub-driver */
|
* Currently only used in pixma_mp810.c sub-driver */
|
||||||
unsigned tpu_offset_added;
|
unsigned tpu_offset_added;
|
||||||
|
|
||||||
|
/** Flag indicating whether a software-lineart scan is in progress
|
||||||
|
* 0 = other scan
|
||||||
|
* 1 = software-lineart scan */
|
||||||
|
unsigned software_lineart;
|
||||||
|
|
||||||
|
/** Threshold for software-lineart scans
|
||||||
|
* Value in percent (0% ... 100%) */
|
||||||
|
unsigned threshold;
|
||||||
|
|
||||||
/** Gamma table. 4096 entries, 12 bit => 8 bit. If \c NULL, default gamma
|
/** Gamma table. 4096 entries, 12 bit => 8 bit. If \c NULL, default gamma
|
||||||
* specified by subdriver will be used. */
|
* specified by subdriver will be used. */
|
||||||
const uint8_t *gamma_table;
|
const uint8_t *gamma_table;
|
||||||
|
@ -284,6 +308,9 @@ struct pixma_scan_param_t
|
||||||
/** \see #pixma_paper_source_t */
|
/** \see #pixma_paper_source_t */
|
||||||
pixma_paper_source_t source;
|
pixma_paper_source_t source;
|
||||||
|
|
||||||
|
/** \see #pixma_scan_mode_t */
|
||||||
|
pixma_scan_mode_t mode;
|
||||||
|
|
||||||
/** The current page # in the same ADF scan session, 0 in non ADF */
|
/** The current page # in the same ADF scan session, 0 in non ADF */
|
||||||
unsigned adf_pageid;
|
unsigned adf_pageid;
|
||||||
};
|
};
|
||||||
|
|
|
@ -304,6 +304,115 @@ pixma_get_time (time_t * sec, uint32_t * usec)
|
||||||
*usec = tv.tv_usec;
|
*usec = tv.tv_usec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* convert 24/48 bit RGB to 8/16 bit grayscale
|
||||||
|
*
|
||||||
|
* Formular: g = (R + G + B) / 3
|
||||||
|
*
|
||||||
|
* sptr: source color scale buffer
|
||||||
|
* gptr: destination gray scale buffer
|
||||||
|
* c == 3: 24 bit RGB -> 8 bit gray
|
||||||
|
* c == 6: 48 bit RGB -> 16 bit gray
|
||||||
|
*/
|
||||||
|
uint8_t *
|
||||||
|
pixma_rgb_to_gray (uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c)
|
||||||
|
{
|
||||||
|
unsigned i, j, g;
|
||||||
|
|
||||||
|
/* PDBG (pixma_dbg (4, "*pixma_rgb_to_gray*****\n")); */
|
||||||
|
|
||||||
|
for (i = 0; i < w; i++)
|
||||||
|
{
|
||||||
|
for (j = 0, g = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
g += *sptr++;
|
||||||
|
if (c == 6) g += (*sptr++ << 8); /* 48 bit RGB: high byte */
|
||||||
|
}
|
||||||
|
|
||||||
|
g /= 3; /* 8 or 16 bit gray */
|
||||||
|
*gptr++ = g;
|
||||||
|
if (c == 6) *gptr++ = (g >> 8); /* 16 bit gray: high byte */
|
||||||
|
}
|
||||||
|
return gptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This code was taken from the genesys backend
|
||||||
|
* This sub-driver has no threshold_curve
|
||||||
|
* uses threshold to control software binarization
|
||||||
|
* @param sp device set up for the scan
|
||||||
|
* @param dst pointer where to store result
|
||||||
|
* @param src pointer to raw data
|
||||||
|
* @param width width of the processed line
|
||||||
|
* @param c 3 for 3-channel single-byte data, 6 for double-byte data
|
||||||
|
* */
|
||||||
|
uint8_t *
|
||||||
|
pixma_binarize_line(pixma_scan_param_t * sp, uint8_t * dst, uint8_t * src, unsigned width, unsigned c)
|
||||||
|
{
|
||||||
|
unsigned j, x, offset;
|
||||||
|
unsigned char mask;
|
||||||
|
uint8_t min, max;
|
||||||
|
unsigned threshold = 0xFF * sp->threshold / 100; /* sp->threshold is 0% ... 100% */
|
||||||
|
|
||||||
|
/* PDBG (pixma_dbg (4, "*pixma_binarize_line***** src = %u, dst = %u, width = %u, c = %u, threshold = %u *****\n",
|
||||||
|
src, dst, width, c, sp->threshold)); */
|
||||||
|
|
||||||
|
/* 16 bit grayscale not supported */
|
||||||
|
if (c == 6)
|
||||||
|
{
|
||||||
|
PDBG (pixma_dbg (1, "*pixma_binarize_line***** Error: 16 bit grayscale not supported\n"));
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* first, color convert to grayscale */
|
||||||
|
pixma_rgb_to_gray(dst, src, width, c);
|
||||||
|
|
||||||
|
/* second, normalize line */
|
||||||
|
min = 255;
|
||||||
|
max = 0;
|
||||||
|
for (x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
if (src[x] > max)
|
||||||
|
{
|
||||||
|
max = src[x];
|
||||||
|
}
|
||||||
|
if (src[x] < min)
|
||||||
|
{
|
||||||
|
min = src[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* safeguard against dark or white areas */
|
||||||
|
if(min>80)
|
||||||
|
min=0;
|
||||||
|
if(max<80)
|
||||||
|
max=255;
|
||||||
|
for (x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
src[x] = ((src[x] - min) * 255) / (max - min);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* third, walk the input buffer, output bits */
|
||||||
|
for (j = 0; j < width; j++)
|
||||||
|
{
|
||||||
|
/* output image location */
|
||||||
|
offset = j % 8;
|
||||||
|
mask = 0x80 >> offset;
|
||||||
|
|
||||||
|
/* lookup threshold */
|
||||||
|
if (src[j] > threshold)
|
||||||
|
*dst &= ~mask; /* white */
|
||||||
|
else
|
||||||
|
*dst |= mask; /* black */
|
||||||
|
|
||||||
|
if (offset == 7)
|
||||||
|
dst++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PDBG (pixma_dbg (4, " *pixma_binarize_line***** ready: src = %u, dst = %u *****\n", src, dst)); */
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pixma_map_status_errno (unsigned status)
|
pixma_map_status_errno (unsigned status)
|
||||||
{
|
{
|
||||||
|
@ -574,6 +683,7 @@ pixma_scan (pixma_t * s, pixma_scan_param_t * sp)
|
||||||
pixma_dbg (3, " dpi=%ux%u offset=(%u,%u) dimension=%ux%u\n",
|
pixma_dbg (3, " dpi=%ux%u offset=(%u,%u) dimension=%ux%u\n",
|
||||||
sp->xdpi, sp->ydpi, sp->x, sp->y, sp->w, sp->h);
|
sp->xdpi, sp->ydpi, sp->x, sp->y, sp->w, sp->h);
|
||||||
pixma_dbg (3, " gamma_table=%p source=%d\n", sp->gamma_table, sp->source);
|
pixma_dbg (3, " gamma_table=%p source=%d\n", sp->gamma_table, sp->source);
|
||||||
|
pixma_dbg (3, " threshold=%d\n", sp->threshold);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->param = sp;
|
s->param = sp;
|
||||||
|
@ -843,6 +953,10 @@ pixma_check_scan_param (pixma_t * s, pixma_scan_param_t * sp)
|
||||||
if (sp->line_size == 0)
|
if (sp->line_size == 0)
|
||||||
sp->line_size = sp->depth / 8 * sp->channels * sp->w;
|
sp->line_size = sp->depth / 8 * sp->channels * sp->w;
|
||||||
sp->image_size = sp->line_size * sp->h;
|
sp->image_size = sp->line_size * sp->h;
|
||||||
|
|
||||||
|
/* image_size for software lineart is counted in bits */
|
||||||
|
if (sp->software_lineart == 1)
|
||||||
|
sp->image_size /= 8;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,6 +188,8 @@ uint8_t pixma_sum_bytes (const void *data, unsigned len);
|
||||||
int pixma_check_dpi (unsigned dpi, unsigned max);
|
int pixma_check_dpi (unsigned dpi, unsigned max);
|
||||||
void pixma_sleep (unsigned long usec);
|
void pixma_sleep (unsigned long usec);
|
||||||
void pixma_get_time (time_t * sec, uint32_t * usec);
|
void pixma_get_time (time_t * sec, uint32_t * usec);
|
||||||
|
uint8_t * pixma_rgb_to_gray (uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c);
|
||||||
|
uint8_t * pixma_binarize_line(pixma_scan_param_t *, uint8_t * dst, uint8_t * src, unsigned width, unsigned c);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/** \name Command related functions */
|
/** \name Command related functions */
|
||||||
|
|
|
@ -567,15 +567,22 @@ has_ccd_sensor (pixma_t * s)
|
||||||
static int
|
static int
|
||||||
is_ccd_grayscale (pixma_t * s)
|
is_ccd_grayscale (pixma_t * s)
|
||||||
{
|
{
|
||||||
return (has_ccd_sensor (s) && (s->param->channels == 1));
|
return (has_ccd_sensor (s) && (s->param->channels == 1) && !s->param->software_lineart);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CCD sensors don't have a Grayscale mode, but use color mode instead */
|
static int
|
||||||
|
is_ccd_lineart (pixma_t * s)
|
||||||
|
{
|
||||||
|
return (has_ccd_sensor (s) && s->param->software_lineart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CCD sensors don't have neither a Grayscale mode nor a Lineart mode,
|
||||||
|
* but use color mode instead */
|
||||||
static unsigned
|
static unsigned
|
||||||
get_cis_ccd_line_size (pixma_t * s)
|
get_cis_ccd_line_size (pixma_t * s)
|
||||||
{
|
{
|
||||||
return (s->param->wx ? s->param->line_size / s->param->w * s->param->wx
|
return ((s->param->wx ? s->param->line_size / s->param->w * s->param->wx
|
||||||
: s->param->line_size) * ((is_ccd_grayscale (s)) ? 3 : 1);
|
: s->param->line_size) * ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
|
@ -654,6 +661,12 @@ send_scan_param (pixma_t * s)
|
||||||
unsigned h = MIN (s->param->h + calc_shifting (s),
|
unsigned h = MIN (s->param->h + calc_shifting (s),
|
||||||
s->cfg->height * s->param->ydpi / 75);
|
s->cfg->height * s->param->ydpi / 75);
|
||||||
|
|
||||||
|
/* TPU scan does not support lineart */
|
||||||
|
if (is_scanning_from_tpu (s) && is_ccd_lineart (s))
|
||||||
|
{
|
||||||
|
return PIXMA_ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
if (mp->generation <= 2)
|
if (mp->generation <= 2)
|
||||||
{
|
{
|
||||||
data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x30, 0);
|
data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x30, 0);
|
||||||
|
@ -665,8 +678,8 @@ send_scan_param (pixma_t * s)
|
||||||
pixma_set_be32 (s->param->y, data + 0x0c);
|
pixma_set_be32 (s->param->y, data + 0x0c);
|
||||||
pixma_set_be32 (raw_width, data + 0x10);
|
pixma_set_be32 (raw_width, data + 0x10);
|
||||||
pixma_set_be32 (h, data + 0x14);
|
pixma_set_be32 (h, data + 0x14);
|
||||||
data[0x18] = ((s->param->channels != 1) || is_ccd_grayscale (s)) ? 0x08 : 0x04;
|
data[0x18] = ((s->param->channels != 1) || is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 0x08 : 0x04;
|
||||||
data[0x19] = s->param->depth * ((is_ccd_grayscale (s)) ? 3 : s->param->channels); /* bits per pixel */
|
data[0x19] = s->param->depth * ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : s->param->channels); /* bits per pixel */
|
||||||
data[0x1a] = (is_scanning_from_tpu (s) ? 1 : 0);
|
data[0x1a] = (is_scanning_from_tpu (s) ? 1 : 0);
|
||||||
data[0x20] = 0xff;
|
data[0x20] = 0xff;
|
||||||
data[0x23] = 0x81;
|
data[0x23] = 0x81;
|
||||||
|
@ -699,13 +712,14 @@ send_scan_param (pixma_t * s)
|
||||||
pixma_set_be32 (s->param->y, data + 0x10);
|
pixma_set_be32 (s->param->y, data + 0x10);
|
||||||
pixma_set_be32 (raw_width, data + 0x14);
|
pixma_set_be32 (raw_width, data + 0x14);
|
||||||
pixma_set_be32 (h, data + 0x18);
|
pixma_set_be32 (h, data + 0x18);
|
||||||
data[0x1c] = ((s->param->channels != 1) || is_ccd_grayscale (s)) ? 0x08 : 0x04;
|
data[0x1c] = ((s->param->channels != 1) || is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 0x08 : 0x04;
|
||||||
|
|
||||||
#ifdef DEBUG_TPU_48
|
#ifdef DEBUG_TPU_48
|
||||||
data[0x1d] = 24;
|
data[0x1d] = 24;
|
||||||
#else
|
#else
|
||||||
data[0x1d] = (is_scanning_from_tpu (s)) ? 48 :
|
data[0x1d] = (is_scanning_from_tpu (s)) ? 48
|
||||||
s->param->depth * ((is_ccd_grayscale (s)) ? 3 : s->param->channels); /* bits per pixel */
|
: (((s->param->depth == 1) ? 8 : s->param->depth)
|
||||||
|
* ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : s->param->channels)); /* bits per pixel */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data[0x1f] = 0x01;
|
data[0x1f] = 0x01;
|
||||||
|
@ -952,26 +966,6 @@ shift_colors (uint8_t * dptr, uint8_t * sptr,
|
||||||
return dptr;
|
return dptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t *
|
|
||||||
rgb_to_gray (uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c)
|
|
||||||
{
|
|
||||||
unsigned i, j, g;
|
|
||||||
|
|
||||||
for (i = 0; i < w; i++)
|
|
||||||
{
|
|
||||||
for (j = 0, g = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
g += *sptr++;
|
|
||||||
if (c == 6) g += (*sptr++ << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
g /= 3;
|
|
||||||
*gptr++ = g;
|
|
||||||
if (c == 6) *gptr++ = (g >> 8);
|
|
||||||
}
|
|
||||||
return gptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reorder_pixels (uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned n,
|
reorder_pixels (uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned n,
|
||||||
unsigned m, unsigned w, unsigned line_size)
|
unsigned m, unsigned w, unsigned line_size)
|
||||||
|
@ -1018,7 +1012,8 @@ post_process_image_data (pixma_t * s, pixma_imagebuf_t * ib)
|
||||||
unsigned c, lines, i, line_size, n, m, cw, cx;
|
unsigned c, lines, i, line_size, n, m, cw, cx;
|
||||||
uint8_t *sptr, *dptr, *gptr, *cptr;
|
uint8_t *sptr, *dptr, *gptr, *cptr;
|
||||||
|
|
||||||
c = ((is_ccd_grayscale (s)) ? 3 : s->param->channels) * s->param->depth / 8;
|
c = ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : s->param->channels)
|
||||||
|
* ((s->param->depth == 1) ? 8 : s->param->depth) / 8;
|
||||||
cw = c * s->param->w;
|
cw = c * s->param->w;
|
||||||
cx = c * s->param->xs;
|
cx = c * s->param->xs;
|
||||||
|
|
||||||
|
@ -1059,9 +1054,12 @@ post_process_image_data (pixma_t * s, pixma_imagebuf_t * ib)
|
||||||
/* Crop line to selected borders */
|
/* Crop line to selected borders */
|
||||||
memmove(cptr, sptr + cx, cw);
|
memmove(cptr, sptr + cx, cw);
|
||||||
|
|
||||||
|
/* Color to Lineart convert for CCD sensor */
|
||||||
|
if (is_ccd_lineart (s))
|
||||||
|
cptr = gptr = pixma_binarize_line (s->param, gptr, cptr, s->param->w, c);
|
||||||
/* Color to Grayscale convert for CCD sensor */
|
/* Color to Grayscale convert for CCD sensor */
|
||||||
if (is_ccd_grayscale (s))
|
else if (is_ccd_grayscale (s))
|
||||||
cptr = gptr = rgb_to_gray (gptr, cptr, s->param->w, c);
|
cptr = gptr = pixma_rgb_to_gray (gptr, cptr, s->param->w, c);
|
||||||
else
|
else
|
||||||
cptr += cw;
|
cptr += cw;
|
||||||
}
|
}
|
||||||
|
@ -1140,14 +1138,39 @@ static int
|
||||||
mp150_check_param (pixma_t * s, pixma_scan_param_t * sp)
|
mp150_check_param (pixma_t * s, pixma_scan_param_t * sp)
|
||||||
{
|
{
|
||||||
mp150_t *mp = (mp150_t *) s->subdriver;
|
mp150_t *mp = (mp150_t *) s->subdriver;
|
||||||
|
unsigned w_max;
|
||||||
|
|
||||||
sp->depth = 8; /* MP150 only supports 8 bit per channel. */
|
/* MP150 only supports 8 bit per channel in color and grayscale mode */
|
||||||
|
if (sp->depth != 1)
|
||||||
|
{
|
||||||
|
sp->software_lineart = 0;
|
||||||
|
sp->depth = 8;
|
||||||
#ifdef TPU_48
|
#ifdef TPU_48
|
||||||
#ifndef DEBUG_TPU_48
|
#ifndef DEBUG_TPU_48
|
||||||
if (sp->source == PIXMA_SOURCE_TPU)
|
if (sp->source == PIXMA_SOURCE_TPU)
|
||||||
#endif
|
#endif
|
||||||
sp->depth = 16; /* TPU in 16 bits mode */
|
sp->depth = 16; /* TPU in 16 bits mode */
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* software lineart */
|
||||||
|
sp->software_lineart = 1;
|
||||||
|
sp->depth = 1;
|
||||||
|
sp->channels = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for software lineart w must be a multiple of 8 */
|
||||||
|
if (sp->software_lineart == 1 && sp->w % 8)
|
||||||
|
{
|
||||||
|
sp->w += 8 - (sp->w % 8);
|
||||||
|
|
||||||
|
/* do not exceed the scanner capability */
|
||||||
|
w_max = s->cfg->width * s->cfg->xdpi / 75;
|
||||||
|
w_max -= w_max % 8;
|
||||||
|
if (sp->w > w_max)
|
||||||
|
sp->w = w_max;
|
||||||
|
}
|
||||||
|
|
||||||
if (mp->generation >= 2)
|
if (mp->generation >= 2)
|
||||||
{
|
{
|
||||||
|
@ -1159,7 +1182,7 @@ mp150_check_param (pixma_t * s, pixma_scan_param_t * sp)
|
||||||
sp->xs = 0;
|
sp->xs = 0;
|
||||||
/*PDBG (pixma_dbg (4, "*mp150_check_param***** Selected origin, origin shift: %i, %i *****\n", sp->x, sp->xs));*/
|
/*PDBG (pixma_dbg (4, "*mp150_check_param***** Selected origin, origin shift: %i, %i *****\n", sp->x, sp->xs));*/
|
||||||
sp->wx = calc_raw_width (mp, sp);
|
sp->wx = calc_raw_width (mp, sp);
|
||||||
sp->line_size = sp->w * sp->channels * (sp->depth / 8); /* bytes per line per color after cropping */
|
sp->line_size = sp->w * sp->channels * (((sp->depth == 1) ? 8 : sp->depth) / 8); /* bytes per line per color after cropping */
|
||||||
/*PDBG (pixma_dbg (4, "*mp150_check_param***** Final scan width and line-size: %i, %i *****\n", sp->wx, sp->line_size));*/
|
/*PDBG (pixma_dbg (4, "*mp150_check_param***** Final scan width and line-size: %i, %i *****\n", sp->wx, sp->line_size));*/
|
||||||
|
|
||||||
/* Some exceptions here for particular devices */
|
/* Some exceptions here for particular devices */
|
||||||
|
@ -1504,6 +1527,7 @@ static const pixma_scan_ops_t pixma_mp150_ops = {
|
||||||
ext_min_dpi, ext_max_dpi, /* ext_min_dpi, ext_max_dpi */ \
|
ext_min_dpi, ext_max_dpi, /* ext_min_dpi, ext_max_dpi */ \
|
||||||
w, h, /* width, height */ \
|
w, h, /* width, height */ \
|
||||||
PIXMA_CAP_EASY_RGB|PIXMA_CAP_GRAY| \
|
PIXMA_CAP_EASY_RGB|PIXMA_CAP_GRAY| \
|
||||||
|
PIXMA_CAP_LINEART| \
|
||||||
PIXMA_CAP_GAMMA_TABLE|PIXMA_CAP_EVENTS|cap \
|
PIXMA_CAP_GAMMA_TABLE|PIXMA_CAP_EVENTS|cap \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -489,7 +489,7 @@ static unsigned
|
||||||
calc_raw_width (const mp810_t * mp, const pixma_scan_param_t * param)
|
calc_raw_width (const mp810_t * mp, const pixma_scan_param_t * param)
|
||||||
{
|
{
|
||||||
unsigned raw_width;
|
unsigned raw_width;
|
||||||
/* NOTE: Actually, we can send arbitary width to MP150. Lines returned
|
/* NOTE: Actually, we can send arbitary width to MP810. Lines returned
|
||||||
are always padded to multiple of 4 or 12 pixels. Is this valid for
|
are always padded to multiple of 4 or 12 pixels. Is this valid for
|
||||||
other models, too? */
|
other models, too? */
|
||||||
if (mp->generation >= 2)
|
if (mp->generation >= 2)
|
||||||
|
@ -517,15 +517,22 @@ has_ccd_sensor (pixma_t * s)
|
||||||
static int
|
static int
|
||||||
is_ccd_grayscale (pixma_t * s)
|
is_ccd_grayscale (pixma_t * s)
|
||||||
{
|
{
|
||||||
return (has_ccd_sensor (s) && (s->param->channels == 1));
|
return (has_ccd_sensor (s) && (s->param->channels == 1) && !s->param->software_lineart);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CCD sensors don't have a Grayscale mode, but use color mode instead */
|
static int
|
||||||
|
is_ccd_lineart (pixma_t * s)
|
||||||
|
{
|
||||||
|
return (has_ccd_sensor (s) && s->param->software_lineart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CCD sensors don't have neither a Grayscale mode nor a Lineart mode,
|
||||||
|
* but use color mode instead */
|
||||||
static unsigned
|
static unsigned
|
||||||
get_cis_ccd_line_size (pixma_t * s)
|
get_cis_ccd_line_size (pixma_t * s)
|
||||||
{
|
{
|
||||||
return (s->param->wx ? s->param->line_size / s->param->w * s->param->wx
|
return ((s->param->wx ? s->param->line_size / s->param->w * s->param->wx
|
||||||
: s->param->line_size) * ((is_ccd_grayscale (s)) ? 3 : 1);
|
: s->param->line_size) * ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
|
@ -679,6 +686,12 @@ send_scan_param (pixma_t * s)
|
||||||
unsigned raw_width = calc_raw_width (mp, s->param);
|
unsigned raw_width = calc_raw_width (mp, s->param);
|
||||||
unsigned h, h1, h2, shifting;
|
unsigned h, h1, h2, shifting;
|
||||||
|
|
||||||
|
/* TPU scan does not support lineart */
|
||||||
|
if (is_scanning_from_tpu (s) && is_ccd_lineart (s))
|
||||||
|
{
|
||||||
|
return PIXMA_ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
shifting = calc_shifting (s);
|
shifting = calc_shifting (s);
|
||||||
h1 = s->param->h + shifting; /* add lines for color shifting */
|
h1 = s->param->h + shifting; /* add lines for color shifting */
|
||||||
/* PDBG (pixma_dbg (4, "* send_scan_param: height calc (choose lesser) 1 %u \n", h1 )); */
|
/* PDBG (pixma_dbg (4, "* send_scan_param: height calc (choose lesser) 1 %u \n", h1 )); */
|
||||||
|
@ -710,8 +723,8 @@ send_scan_param (pixma_t * s)
|
||||||
pixma_set_be32 (s->param->y, data + 0x0c);
|
pixma_set_be32 (s->param->y, data + 0x0c);
|
||||||
pixma_set_be32 (raw_width, data + 0x10);
|
pixma_set_be32 (raw_width, data + 0x10);
|
||||||
pixma_set_be32 (h, data + 0x14);
|
pixma_set_be32 (h, data + 0x14);
|
||||||
data[0x18] = ((s->param->channels != 1) || is_ccd_grayscale (s)) ? 0x08 : 0x04;
|
data[0x18] = ((s->param->channels != 1) || is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 0x08 : 0x04;
|
||||||
data[0x19] = s->param->depth * ((is_ccd_grayscale (s)) ? 3 : s->param->channels); /* bits per pixel */
|
data[0x19] = s->param->depth * ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : s->param->channels); /* bits per pixel */
|
||||||
data[0x1a] = (is_scanning_from_tpu (s) ? 1 : 0);
|
data[0x1a] = (is_scanning_from_tpu (s) ? 1 : 0);
|
||||||
data[0x20] = 0xff;
|
data[0x20] = 0xff;
|
||||||
data[0x23] = 0x81;
|
data[0x23] = 0x81;
|
||||||
|
@ -752,13 +765,14 @@ send_scan_param (pixma_t * s)
|
||||||
pixma_set_be32 (s->param->y, data + 0x10);
|
pixma_set_be32 (s->param->y, data + 0x10);
|
||||||
pixma_set_be32 (raw_width, data + 0x14);
|
pixma_set_be32 (raw_width, data + 0x14);
|
||||||
pixma_set_be32 (h, data + 0x18);
|
pixma_set_be32 (h, data + 0x18);
|
||||||
data[0x1c] = ((s->param->channels != 1) || is_ccd_grayscale (s)) ? 0x08 : 0x04;
|
data[0x1c] = ((s->param->channels != 1) || is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 0x08 : 0x04;
|
||||||
|
|
||||||
#ifdef DEBUG_TPU_48
|
#ifdef DEBUG_TPU_48
|
||||||
data[0x1d] = 24;
|
data[0x1d] = 24;
|
||||||
#else
|
#else
|
||||||
data[0x1d] = (is_scanning_from_tpu (s)) ? 48 :
|
data[0x1d] = (is_scanning_from_tpu (s)) ? 48
|
||||||
s->param->depth * ((is_ccd_grayscale (s)) ? 3 : s->param->channels); /* bits per pixel */
|
: (((s->param->depth == 1) ? 8 : s->param->depth)
|
||||||
|
* ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : s->param->channels)); /* bits per pixel */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data[0x1f] = 0x01; /* for 9000F this appears to be 0x00, not sure if that is because of positives */
|
data[0x1f] = 0x01; /* for 9000F this appears to be 0x00, not sure if that is because of positives */
|
||||||
|
@ -1080,26 +1094,6 @@ shift_colorsCS9000 (uint8_t * dptr, uint8_t * sptr,
|
||||||
return dptr;
|
return dptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t *
|
|
||||||
rgb_to_gray (uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c)
|
|
||||||
{
|
|
||||||
unsigned i, j, g;
|
|
||||||
|
|
||||||
for (i = 0; i < w; i++)
|
|
||||||
{
|
|
||||||
for (j = 0, g = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
g += *sptr++;
|
|
||||||
if (c == 6) g += (*sptr++ << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
g /= 3;
|
|
||||||
*gptr++ = g;
|
|
||||||
if (c == 6) *gptr++ = (g >> 8);
|
|
||||||
}
|
|
||||||
return gptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* under some conditions some scanners have sub images in one line */
|
/* under some conditions some scanners have sub images in one line */
|
||||||
/* e.g. doubled image, line size = 8 */
|
/* e.g. doubled image, line size = 8 */
|
||||||
/* line before reordering: px1 px3 px5 px7 px2 px4 px6 px8 */
|
/* line before reordering: px1 px3 px5 px7 px2 px4 px6 px8 */
|
||||||
|
@ -1292,7 +1286,8 @@ post_process_image_data (pixma_t * s, pixma_imagebuf_t * ib)
|
||||||
test=0;
|
test=0;
|
||||||
jumplines=0;
|
jumplines=0;
|
||||||
|
|
||||||
c = ((is_ccd_grayscale (s)) ? 3 : s->param->channels) * s->param->depth / 8;
|
c = ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : s->param->channels)
|
||||||
|
* ((s->param->depth == 1) ? 8 : s->param->depth) / 8;
|
||||||
cw = c * s->param->w;
|
cw = c * s->param->w;
|
||||||
cx = c * s->param->xs;
|
cx = c * s->param->xs;
|
||||||
|
|
||||||
|
@ -1440,9 +1435,12 @@ post_process_image_data (pixma_t * s, pixma_imagebuf_t * ib)
|
||||||
memmove(cptr, sptr + cx, cw);
|
memmove(cptr, sptr + cx, cw);
|
||||||
/* PDBG (pixma_dbg (4, "*post_process_image_data***** crop line: cx=%u, cw=%u ***** \n", cx, cw)); */
|
/* PDBG (pixma_dbg (4, "*post_process_image_data***** crop line: cx=%u, cw=%u ***** \n", cx, cw)); */
|
||||||
|
|
||||||
|
/* Color to Lineart convert for CCD sensor */
|
||||||
|
if (is_ccd_lineart (s))
|
||||||
|
cptr = gptr = pixma_binarize_line (s->param, gptr, cptr, s->param->w, c);
|
||||||
/* Color to Grayscale convert for CCD sensor */
|
/* Color to Grayscale convert for CCD sensor */
|
||||||
if (is_ccd_grayscale (s))
|
else if (is_ccd_grayscale (s))
|
||||||
cptr = gptr = rgb_to_gray (gptr, cptr, s->param->w, c);
|
cptr = gptr = pixma_rgb_to_gray (gptr, cptr, s->param->w, c);
|
||||||
else
|
else
|
||||||
cptr += cw;
|
cptr += cw;
|
||||||
}
|
}
|
||||||
|
@ -1533,14 +1531,42 @@ static int
|
||||||
mp810_check_param (pixma_t * s, pixma_scan_param_t * sp)
|
mp810_check_param (pixma_t * s, pixma_scan_param_t * sp)
|
||||||
{
|
{
|
||||||
mp810_t *mp = (mp810_t *) s->subdriver;
|
mp810_t *mp = (mp810_t *) s->subdriver;
|
||||||
|
unsigned w_max;
|
||||||
|
|
||||||
sp->depth = 8; /* MP150 only supports 8 bit per channel. */
|
/* PDBG (pixma_dbg (4, "*mp810_check_param***** Initially: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u *****\n",
|
||||||
|
sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx)); */
|
||||||
|
|
||||||
|
/* MP810 only supports 8 bit per channel in color and grayscale mode */
|
||||||
|
if (sp->depth != 1)
|
||||||
|
{
|
||||||
|
sp->software_lineart = 0;
|
||||||
|
sp->depth = 8;
|
||||||
#ifdef TPU_48
|
#ifdef TPU_48
|
||||||
#ifndef DEBUG_TPU_48
|
#ifndef DEBUG_TPU_48
|
||||||
if (sp->source == PIXMA_SOURCE_TPU)
|
if (sp->source == PIXMA_SOURCE_TPU)
|
||||||
#endif
|
#endif
|
||||||
sp->depth = 16; /* TPU in 16 bits mode */
|
sp->depth = 16; /* TPU in 16 bits mode */
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* software lineart */
|
||||||
|
sp->software_lineart = 1;
|
||||||
|
sp->depth = 1;
|
||||||
|
sp->channels = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for software lineart w must be a multiple of 8 */
|
||||||
|
if (sp->software_lineart == 1 && sp->w % 8)
|
||||||
|
{
|
||||||
|
sp->w += 8 - (sp->w % 8);
|
||||||
|
|
||||||
|
/* do not exceed the scanner capability */
|
||||||
|
w_max = s->cfg->width * s->cfg->xdpi / 75;
|
||||||
|
w_max -= w_max % 8;
|
||||||
|
if (sp->w > w_max)
|
||||||
|
sp->w = w_max;
|
||||||
|
}
|
||||||
|
|
||||||
if (sp->source == PIXMA_SOURCE_TPU && !sp->tpu_offset_added)
|
if (sp->source == PIXMA_SOURCE_TPU && !sp->tpu_offset_added)
|
||||||
{
|
{
|
||||||
|
@ -1620,7 +1646,7 @@ mp810_check_param (pixma_t * s, pixma_scan_param_t * sp)
|
||||||
/* PDBG (pixma_dbg (4, "*mp810_check_param***** (else) xs=0 Selected origin, origin shift: %u, %u *****\n", sp->x, sp->xs)); */
|
/* PDBG (pixma_dbg (4, "*mp810_check_param***** (else) xs=0 Selected origin, origin shift: %u, %u *****\n", sp->x, sp->xs)); */
|
||||||
}
|
}
|
||||||
sp->wx = calc_raw_width (mp, sp);
|
sp->wx = calc_raw_width (mp, sp);
|
||||||
sp->line_size = sp->w * sp->channels * (sp->depth / 8); /* bytes per line per color after cropping */
|
sp->line_size = sp->w * sp->channels * (((sp->depth == 1) ? 8 : sp->depth) / 8); /* bytes per line per color after cropping */
|
||||||
/* PDBG (pixma_dbg (4, "*mp810_check_param***** (else) Final scan width and line-size: %u, %"PRIu64" *****\n", sp->wx, sp->line_size)); */
|
/* PDBG (pixma_dbg (4, "*mp810_check_param***** (else) Final scan width and line-size: %u, %"PRIu64" *****\n", sp->wx, sp->line_size)); */
|
||||||
|
|
||||||
if (sp->source == PIXMA_SOURCE_FLATBED)
|
if (sp->source == PIXMA_SOURCE_FLATBED)
|
||||||
|
@ -1674,6 +1700,9 @@ mp810_check_param (pixma_t * s, pixma_scan_param_t * sp)
|
||||||
sp->ydpi = sp->xdpi;
|
sp->ydpi = sp->xdpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PDBG (pixma_dbg (4, "*mp810_check_param***** Finally: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u *****\n",
|
||||||
|
sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx)); */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1971,6 +2000,7 @@ static const pixma_scan_ops_t pixma_mp810_ops = {
|
||||||
ext_min_dpi, ext_max_dpi, /* ext_min_dpi, ext_max_dpi */ \
|
ext_min_dpi, ext_max_dpi, /* ext_min_dpi, ext_max_dpi */ \
|
||||||
w, h, /* width, height */ \
|
w, h, /* width, height */ \
|
||||||
PIXMA_CAP_EASY_RGB|PIXMA_CAP_GRAY| \
|
PIXMA_CAP_EASY_RGB|PIXMA_CAP_GRAY| \
|
||||||
|
PIXMA_CAP_LINEART| \
|
||||||
PIXMA_CAP_GAMMA_TABLE|PIXMA_CAP_EVENTS|cap \
|
PIXMA_CAP_GAMMA_TABLE|PIXMA_CAP_EVENTS|cap \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* Automatically generated from pixma_sane.c */
|
/* Automatically generated from pixma_sane.c */
|
||||||
static const SANE_Range constraint_gamma_table = { 0, 255, 0 };
|
static const SANE_Range constraint_gamma_table = { 0, 255, 0 };
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
find_string_in_list (SANE_String_Const str, const SANE_String_Const * list)
|
find_string_in_list (SANE_String_Const str, const SANE_String_Const * list)
|
||||||
{
|
{
|
||||||
|
@ -67,7 +66,7 @@ build_option_descriptors (struct pixma_sane_t *ss)
|
||||||
sod->constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
sod->constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
||||||
sod->constraint.string_list = ss->mode_list;
|
sod->constraint.string_list = ss->mode_list;
|
||||||
OPT_IN_CTX[opt_mode].info = SANE_INFO_RELOAD_PARAMS;
|
OPT_IN_CTX[opt_mode].info = SANE_INFO_RELOAD_PARAMS;
|
||||||
opt->def.s = SANE_VALUE_SCAN_MODE_COLOR;
|
opt->def.s = SANE_I18N (ss->mode_list[0]);
|
||||||
opt->val.w = find_string_in_list (opt->def.s, sod->constraint.string_list);
|
opt->val.w = find_string_in_list (opt->def.s, sod->constraint.string_list);
|
||||||
|
|
||||||
opt = &(OPT_IN_CTX[opt_source]);
|
opt = &(OPT_IN_CTX[opt_source]);
|
||||||
|
@ -250,6 +249,29 @@ build_option_descriptors (struct pixma_sane_t *ss)
|
||||||
opt->def.w = 0;
|
opt->def.w = 0;
|
||||||
opt->val.w = 0;
|
opt->val.w = 0;
|
||||||
|
|
||||||
|
opt = &(OPT_IN_CTX[opt__group_5]);
|
||||||
|
sod = &opt->sod;
|
||||||
|
sod->type = SANE_TYPE_GROUP;
|
||||||
|
sod->title = SANE_I18N ("Extras");
|
||||||
|
sod->desc = sod->title;
|
||||||
|
|
||||||
|
opt = &(OPT_IN_CTX[opt_threshold]);
|
||||||
|
sod = &opt->sod;
|
||||||
|
sod->type = SANE_TYPE_INT;
|
||||||
|
sod->title = SANE_TITLE_THRESHOLD;
|
||||||
|
sod->desc = SANE_DESC_THRESHOLD;
|
||||||
|
sod->name = "threshold";
|
||||||
|
sod->unit = SANE_UNIT_PERCENT;
|
||||||
|
sod->size = 1 * sizeof (SANE_Word);
|
||||||
|
sod->cap =
|
||||||
|
SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_AUTOMATIC |
|
||||||
|
SANE_CAP_INACTIVE;
|
||||||
|
sod->constraint_type = SANE_CONSTRAINT_NONE;
|
||||||
|
OPT_IN_CTX[opt_threshold].info = 0;
|
||||||
|
opt->def.w = 50;
|
||||||
|
opt->val.w = 50;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ typedef enum
|
||||||
opt_button_update,
|
opt_button_update,
|
||||||
opt_button_1,
|
opt_button_1,
|
||||||
opt_button_2,
|
opt_button_2,
|
||||||
|
opt__group_5,
|
||||||
|
opt_threshold,
|
||||||
opt_last
|
opt_last
|
||||||
} option_t;
|
} option_t;
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue