Merge branch 'pixma/gamma_table' into 'master'

Pixma: fix internal generated gamma table

See merge request sane-project/backends!295
merge-requests/244/head
Rolf Bensch 2020-06-05 20:58:07 +00:00
commit edace214b2
8 zmienionych plików z 213 dodań i 116 usunięć

Wyświetl plik

@ -542,6 +542,8 @@ control_scalar_option (pixma_sane_t * ss, SANE_Int n, SANE_Action a, void *v,
option_descriptor_t *opt = &(OPT_IN_CTX[n]); option_descriptor_t *opt = &(OPT_IN_CTX[n]);
SANE_Word val; SANE_Word val;
/* PDBG (pixma_dbg (4, "*control_scalar_option***** n = %u, a = %u\n", n, a)); */
switch (a) switch (a)
{ {
case SANE_ACTION_GET_VALUE: case SANE_ACTION_GET_VALUE:
@ -605,6 +607,8 @@ control_string_option (pixma_sane_t * ss, SANE_Int n, SANE_Action a, void *v,
const SANE_String_Const *slist = opt->sod.constraint.string_list; const SANE_String_Const *slist = opt->sod.constraint.string_list;
SANE_String str = (SANE_String) v; SANE_String str = (SANE_String) v;
/* PDBG (pixma_dbg (4, "*control_string_option***** n = %u, a = %u\n", n, a)); */
if (opt->sod.constraint_type == SANE_CONSTRAINT_NONE) if (opt->sod.constraint_type == SANE_CONSTRAINT_NONE)
{ {
switch (a) switch (a)
@ -657,6 +661,7 @@ static SANE_Status
control_option (pixma_sane_t * ss, SANE_Int n, control_option (pixma_sane_t * ss, SANE_Int n,
SANE_Action a, void *v, SANE_Int * info) SANE_Action a, void *v, SANE_Int * info)
{ {
SANE_Option_Descriptor *sod = &SOD (n);
int result, i; int result, i;
const pixma_config_t *cfg; const pixma_config_t *cfg;
SANE_Int dummy; SANE_Int dummy;
@ -674,25 +679,59 @@ control_option (pixma_sane_t * ss, SANE_Int n,
switch (n) switch (n)
{ {
case opt_gamma_table: case opt_gamma_table:
switch (a) {
{ int table_size = sod->size / sizeof (SANE_Word);
case SANE_ACTION_SET_VALUE: int byte_cnt = table_size == 1024 ? 2 : 1;
clamp_value (ss, n, v, info);
for (i = 0; i != 4096; i++) switch (a)
ss->gamma_table[i] = *((SANE_Int *) v + i); {
break; case SANE_ACTION_SET_VALUE:
case SANE_ACTION_GET_VALUE: PDBG (pixma_dbg (4, "*control_option***** opt_gamma_table: SANE_ACTION_SET_VALUE with %d values ***** \n", table_size));
for (i = 0; i != 4096; i++) clamp_value (ss, n, v, info);
*((SANE_Int *) v + i) = ss->gamma_table[i]; if (byte_cnt == 1)
break; {
case SANE_ACTION_SET_AUTO: for (i = 0; i < table_size; i++)
pixma_fill_gamma_table (AUTO_GAMMA, ss->gamma_table, ss->gamma_table[i] = *((SANE_Int *) v + i);
sizeof (ss->gamma_table)); }
break; else
default: {
return SANE_STATUS_UNSUPPORTED; for (i = 0; i < table_size; i++)
} {
return SANE_STATUS_GOOD; ss->gamma_table[i * 2] = *((SANE_Int *) v + i);
ss->gamma_table[i * 2 + 1] = *((uint8_t *)((SANE_Int *) v + i) + 1);
}
}
/* PDBG (pixma_hexdump (4, (uint8_t *)v, table_size * 4)); */
/* PDBG (pixma_hexdump (4, ss->gamma_table, table_size * byte_cnt)); */
break;
case SANE_ACTION_GET_VALUE:
PDBG (pixma_dbg (4, "*control_option***** opt_gamma_table: SANE_ACTION_GET_VALUE ***** \n"));
if (byte_cnt == 1)
{
for (i = 0; i < table_size; i++)
*((SANE_Int *) v + i) = ss->gamma_table[i];
}
else
{
for (i = 0; i < table_size; i++)
{
*((SANE_Int *) v + i) = ss->gamma_table[i * 2];
*((uint8_t *)((SANE_Int *) v + i) + 1) = ss->gamma_table[i * 2 + 1];
}
}
break;
case SANE_ACTION_SET_AUTO:
PDBG (pixma_dbg (4, "*control_option***** opt_gamma_table: SANE_ACTION_SET_AUTO with gamma=%f ***** \n",
SANE_UNFIX (OVAL (opt_gamma).w)));
pixma_fill_gamma_table (SANE_UNFIX (OVAL (opt_gamma).w),
ss->gamma_table, table_size);
/* PDBG (pixma_hexdump (4, ss->gamma_table, table_size * byte_cnt)); */
break;
default:
return SANE_STATUS_UNSUPPORTED;
}
return SANE_STATUS_GOOD;
}
case opt_button_update: case opt_button_update:
if (a == SANE_ACTION_SET_VALUE) if (a == SANE_ACTION_SET_VALUE)
@ -745,15 +784,24 @@ control_option (pixma_sane_t * ss, SANE_Int n,
{ {
if (enable_option (ss, opt_gamma_table, OVAL (opt_custom_gamma).b)) if (enable_option (ss, opt_gamma_table, OVAL (opt_custom_gamma).b))
*info |= SANE_INFO_RELOAD_OPTIONS; *info |= SANE_INFO_RELOAD_OPTIONS;
if (OVAL (opt_custom_gamma).b)
sane_control_option (ss, opt_gamma_table, SANE_ACTION_SET_AUTO,
NULL, NULL);
} }
break; break;
case opt_gamma: case opt_gamma:
if (a == SANE_ACTION_SET_VALUE || a == SANE_ACTION_SET_AUTO) if (a == SANE_ACTION_SET_VALUE || a == SANE_ACTION_SET_AUTO)
{ {
/* PDBG (pixma_dbg (4, "*control_option***** gamma = %f *\n", int table_size = SOD (opt_gamma_table).size / sizeof(SANE_Word);
SANE_UNFIX (OVAL (opt_gamma).w))); */ PDBG (pixma_dbg (4, "*control_option***** gamma = %f *\n",
SANE_UNFIX (OVAL (opt_gamma).w)));
PDBG (pixma_dbg (4, "*control_option***** table size = %d *\n",
(int)(SOD (opt_gamma_table).size / sizeof (SANE_Word))));
pixma_fill_gamma_table (SANE_UNFIX (OVAL (opt_gamma).w), pixma_fill_gamma_table (SANE_UNFIX (OVAL (opt_gamma).w),
ss->gamma_table, sizeof (ss->gamma_table)); ss->gamma_table, table_size);
/* PDBG (pixma_hexdump (4, ss->gamma_table,
table_size == 1024 ? 2048 : table_size)); */
} }
break; break;
case opt_mode: case opt_mode:
@ -827,8 +875,8 @@ print_scan_param (int level, const pixma_scan_param_t * sp)
sp->line_size, sp->image_size, sp->channels, sp->depth); sp->line_size, sp->image_size, sp->channels, sp->depth);
pixma_dbg (level, " dpi=%ux%u offset=(%u,%u) dimension=%ux%u\n", pixma_dbg (level, " 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 (level, " gamma_table=%p source=%d\n", sp->gamma_table, pixma_dbg (level, " gamma=%f gamma_table=%p source=%d\n", sp->gamma,
sp->source); sp->gamma_table, sp->source);
pixma_dbg (level, " adf-wait=%d\n", sp->adf_wait); pixma_dbg (level, " adf-wait=%d\n", sp->adf_wait);
} }
#endif #endif
@ -873,7 +921,8 @@ calc_scan_param (pixma_sane_t * ss, pixma_scan_param_t * sp)
sp->h = 1; sp->h = 1;
sp->tpu_offset_added = 0; sp->tpu_offset_added = 0;
sp->gamma_table = (OVAL (opt_custom_gamma).b) ? ss->gamma_table : NULL; sp->gamma = SANE_UNFIX (OVAL (opt_gamma).w);
sp->gamma_table = ss->gamma_table;
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->mode = ss->mode_map[OVAL (opt_mode).w];
sp->adf_pageid = ss->page_count; sp->adf_pageid = ss->page_count;
@ -898,6 +947,8 @@ init_option_descriptors (pixma_sane_t * ss)
cfg = pixma_get_config (ss->s); cfg = pixma_get_config (ss->s);
/* PDBG (pixma_dbg (4, "*init_option_descriptors*****\n")); */
/* setup range for the scan area. */ /* setup range for the scan area. */
ss->xrange.min = SANE_FIX (0); ss->xrange.min = SANE_FIX (0);
ss->xrange.max = SANE_FIX (cfg->width / 75.0 * 25.4); ss->xrange.max = SANE_FIX (cfg->width / 75.0 * 25.4);
@ -945,11 +996,32 @@ init_option_descriptors (pixma_sane_t * ss)
/* Enable options that are available only in some scanners. */ /* Enable options that are available only in some scanners. */
if (cfg->cap & PIXMA_CAP_GAMMA_TABLE) if (cfg->cap & PIXMA_CAP_GAMMA_TABLE)
{ {
SANE_Option_Descriptor *sod = &SOD (opt_gamma_table);
/* some scanners have a large gamma table with 4096 entries */
if (cfg->cap & PIXMA_CAP_GT_4096)
{
static const SANE_Range constraint_gamma_table_4096 = { 0,0xff,0 };
sod->desc = SANE_I18N("Gamma-correction table with 4096 entries. In color mode this option equally affects the red, green, and blue channels simultaneously (i.e., it is an intensity gamma table).");
sod->size = 4096 * sizeof(SANE_Word);
sod->constraint.range = &constraint_gamma_table_4096;
}
/* PDBG (pixma_dbg (4, "*%s***** PIXMA_CAP_GAMMA_TABLE ***** \n",
__func__)); */
/* PDBG (pixma_dbg (4, "%s: gamma_table_contraint.max = %d\n",
__func__, sod->constraint.range->max)); */
/* PDBG (pixma_dbg (4, "%s: gamma_table_size = %d\n",
__func__, sod->size / sizeof(SANE_Word))); */
/* activate option gamma */
enable_option (ss, opt_gamma, SANE_TRUE); enable_option (ss, opt_gamma, SANE_TRUE);
sane_control_option (ss, opt_gamma, SANE_ACTION_SET_AUTO,
NULL, NULL);
/* activate option custom gamma table */
enable_option (ss, opt_custom_gamma, SANE_TRUE); enable_option (ss, opt_custom_gamma, SANE_TRUE);
sane_control_option (ss, opt_custom_gamma, SANE_ACTION_SET_AUTO, sane_control_option (ss, opt_custom_gamma, SANE_ACTION_SET_AUTO,
NULL, NULL); NULL, NULL);
pixma_fill_gamma_table (AUTO_GAMMA, ss->gamma_table, 4096);
} }
enable_option (ss, opt_button_controlled, enable_option (ss, opt_button_controlled,
((cfg->cap & PIXMA_CAP_EVENTS) != 0)); ((cfg->cap & PIXMA_CAP_EVENTS) != 0));
@ -2043,15 +2115,15 @@ type group
title Gamma title Gamma
type bool custom-gamma type bool custom-gamma
default SANE_TRUE default SANE_FALSE
title @SANE_TITLE_CUSTOM_GAMMA title @SANE_TITLE_CUSTOM_GAMMA
desc @SANE_DESC_CUSTOM_GAMMA desc @SANE_DESC_CUSTOM_GAMMA
cap soft_select soft_detect automatic inactive cap soft_select soft_detect automatic inactive
type int gamma-table[4096] type int gamma-table[1024]
constraint (0,255,0) constraint (0,0xffff,0)
title @SANE_TITLE_GAMMA_VECTOR title @SANE_TITLE_GAMMA_VECTOR
desc @SANE_DESC_GAMMA_VECTOR desc Gamma-correction table with 1024 entries. In color mode this option equally affects the red, green, and blue channels simultaneously (i.e., it is an intensity gamma table).
cap soft_select soft_detect automatic inactive cap soft_select soft_detect automatic inactive
type fixed gamma type fixed gamma

Wyświetl plik

@ -158,6 +158,10 @@ typedef uint32_t uint32_t;
#define PIXMA_CAP_TPUIR ((1 << 11) | PIXMA_CAP_TPU) #define PIXMA_CAP_TPUIR ((1 << 11) | PIXMA_CAP_TPU)
#define PIXMA_CAP_ADF_WAIT (1 << 12) #define PIXMA_CAP_ADF_WAIT (1 << 12)
#define PIXMA_CAP_ADF_JPEG (1 << 13) #define PIXMA_CAP_ADF_JPEG (1 << 13)
#define PIXMA_CAP_GT_4096 (1 << 14) /* gamma table has 4096 8-bit values
* only generation 1 scanners
* usually gamma table has 1024 16-bit values
*/
#define PIXMA_CAP_EXPERIMENT (1 << 31) #define PIXMA_CAP_EXPERIMENT (1 << 31)
/**@}*/ /**@}*/
@ -340,6 +344,9 @@ struct pixma_scan_param_t
* specified by subdriver will be used. */ * specified by subdriver will be used. */
const uint8_t *gamma_table; const uint8_t *gamma_table;
/** value for auto generated gamma table */
double gamma;
/** \see #pixma_paper_source_t */ /** \see #pixma_paper_source_t */
pixma_paper_source_t source; pixma_paper_source_t source;

Wyświetl plik

@ -880,7 +880,7 @@ pixma_scan (pixma_t * s, pixma_scan_param_t * sp)
sp->line_size, sp->image_size, sp->channels, sp->depth); sp->line_size, sp->image_size, sp->channels, sp->depth);
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=%f gamma_table=%p source=%d\n", sp->gamma, sp->gamma_table, sp->source);
pixma_dbg (3, " threshold=%d threshold_curve=%d\n", sp->threshold, sp->threshold_curve); pixma_dbg (3, " threshold=%d threshold_curve=%d\n", sp->threshold, sp->threshold_curve);
pixma_dbg (3, " adf-wait=%d\n", sp->adf_wait); pixma_dbg (3, " adf-wait=%d\n", sp->adf_wait);
pixma_dbg (3, " ADF page count: %d\n", sp->adf_pageid); pixma_dbg (3, " ADF page count: %d\n", sp->adf_pageid);
@ -1186,14 +1186,35 @@ pixma_get_config (pixma_t * s)
void void
pixma_fill_gamma_table (double gamma, uint8_t * table, unsigned n) pixma_fill_gamma_table (double gamma, uint8_t * table, unsigned n)
{ {
int i; unsigned i;
double r_gamma = 1.0 / gamma; double r_gamma = 1.0 / gamma;
double out_scale = 255.0;
double in_scale = 1.0 / (n - 1); double in_scale = 1.0 / (n - 1);
for (i = 0; (unsigned) i != n; i++) /* 8-bits gamma table
* for generation 1 scanners
*/
if (n == 4096)
{ {
table[i] = (int) (out_scale * pow (i * in_scale, r_gamma) + 0.5); double out_scale = 255.0;
for (i = 0; (unsigned) i != n; i++)
{
table[i] = (int) (out_scale * pow (i * in_scale, r_gamma) + 0.5);
}
}
/* 16-bits gamma table */
else
{
double out_scale = 65535.0;
uint16_t value;
for (i = 0; i < n; i++)
{
value = (uint16_t) (out_scale * pow (i * in_scale, r_gamma) + 0.5);
table[2 * i] = (uint8_t) (value & 0xff);
table[2 * i + 1] = (uint8_t) (value >> 8);
}
} }
} }

Wyświetl plik

@ -85,7 +85,6 @@
4096 = size of gamma table. 24 = header + checksum */ 4096 = size of gamma table. 24 = header + checksum */
#define IMAGE_BLOCK_SIZE (512*1024) #define IMAGE_BLOCK_SIZE (512*1024)
#define CMDBUF_SIZE (4096 + 24) #define CMDBUF_SIZE (4096 + 24)
#define DEFAULT_GAMMA 2.0 /***** Gamma different from 1.0 is potentially impacting color profile generation *****/
#define UNKNOWN_PID 0xffff #define UNKNOWN_PID 0xffff
@ -567,42 +566,45 @@ send_gamma_table (pixma_t * s)
const uint8_t *lut = s->param->gamma_table; const uint8_t *lut = s->param->gamma_table;
uint8_t *data; uint8_t *data;
if (mp->generation == 1) if (s->cfg->cap & PIXMA_CAP_GT_4096)
{ {
data = pixma_newcmd (&mp->cb, cmd_gamma, 4096 + 8, 0); data = pixma_newcmd (&mp->cb, cmd_gamma, 4096 + 8, 0);
data[0] = (s->param->channels == 3) ? 0x10 : 0x01; data[0] = (s->param->channels == 3) ? 0x10 : 0x01;
pixma_set_be16 (0x1004, data + 2); pixma_set_be16 (0x1004, data + 2);
if (lut) if (lut)
memcpy (data + 4, lut, 4096); {
/* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 4096 bytes from LUT ***** \n")); */
/* PDBG (pixma_hexdump (4, lut, 4096)); */
memcpy (data + 4, lut, 4096);
}
else else
pixma_fill_gamma_table (DEFAULT_GAMMA, data + 4, 4096); {
/* fallback: we should never see this */
PDBG (pixma_dbg (4, "*send_gamma_table***** Generate 4096 bytes Table with %f ***** \n",
s->param->gamma));
pixma_fill_gamma_table (s->param->gamma, data + 4, 4096);
/* PDBG (pixma_hexdump (4, data + 4, 4096)); */
}
} }
else else
{ {
/* FIXME: Gamma table for 2nd generation: 1024 * uint16_le */ /* Gamma table for 2nd+ generation: 1024 * uint16_le */
data = pixma_newcmd (&mp->cb, cmd_gamma, 2048 + 8, 0); data = pixma_newcmd (&mp->cb, cmd_gamma, 1024 * 2 + 8, 0);
data[0] = 0x10; data[0] = 0x10;
pixma_set_be16 (0x0804, data + 2); pixma_set_be16 (0x0804, data + 2);
if (lut) if (lut)
{ {
int i; /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); */
for (i = 0; i < 1024; i++) /* PDBG (pixma_hexdump (4, lut, 1024 * 2)); */
{ memcpy (data + 4, lut, 1024 * 2);
int j = (i << 2) + (i >> 8);
data[4 + 2 * i + 0] = lut[j];
data[4 + 2 * i + 1] = lut[j];
}
} }
else else
{ {
int i; /* fallback: we should never see this */
pixma_fill_gamma_table (DEFAULT_GAMMA, data + 4, 2048); PDBG (pixma_dbg (4, "*send_gamma_table***** Generate 1024 * 2 Table with %f ***** \n",
for (i = 0; i < 1024; i++) s->param->gamma));
{ pixma_fill_gamma_table (s->param->gamma, data + 4, 1024);
int j = (i << 1) + (i >> 9); /* PDBG (pixma_hexdump (4, data + 4, 1024 * 2)); */
data[4 + 2 * i + 0] = data[4 + j];
data[4 + 2 * i + 1] = data[4 + j];
}
} }
} }
return pixma_exec (s, &mp->cb); return pixma_exec (s, &mp->cb);
@ -1220,8 +1222,8 @@ 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;
/* PDBG (pixma_dbg (4, "*mp150_check_param***** Initially: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u *****\n", /* PDBG (pixma_dbg (4, "*mp150_check_param***** Initially: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u, gamma=%f *****\n",
sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx)); */ sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx, sp->gamma)); */
/* MP150 only supports 8 bit per channel in color and grayscale mode */ /* MP150 only supports 8 bit per channel in color and grayscale mode */
if (sp->depth != 1) if (sp->depth != 1)
@ -1612,11 +1614,11 @@ static const pixma_scan_ops_t pixma_mp150_ops = {
const pixma_config_t pixma_mp150_devices[] = { const pixma_config_t pixma_mp150_devices[] = {
/* Generation 1: CIS */ /* Generation 1: CIS */
DEVICE ("Canon PIXMA MP150", "MP150", MP150_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), DEVICE ("Canon PIXMA MP150", "MP150", MP150_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096),
DEVICE ("Canon PIXMA MP170", "MP170", MP170_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), DEVICE ("Canon PIXMA MP170", "MP170", MP170_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096),
DEVICE ("Canon PIXMA MP450", "MP450", MP450_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), DEVICE ("Canon PIXMA MP450", "MP450", MP450_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096),
DEVICE ("Canon PIXMA MP500", "MP500", MP500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), DEVICE ("Canon PIXMA MP500", "MP500", MP500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096),
DEVICE ("Canon PIXMA MP530", "MP530", MP530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), DEVICE ("Canon PIXMA MP530", "MP530", MP530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_GT_4096 | PIXMA_CAP_ADF),
/* Generation 2: CIS */ /* Generation 2: CIS */
DEVICE ("Canon PIXMA MP140", "MP140", MP140_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), DEVICE ("Canon PIXMA MP140", "MP140", MP140_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),

Wyświetl plik

@ -91,7 +91,6 @@
4096 = size of gamma table. 24 = header + checksum */ 4096 = size of gamma table. 24 = header + checksum */
#define IMAGE_BLOCK_SIZE (512*1024) #define IMAGE_BLOCK_SIZE (512*1024)
#define CMDBUF_SIZE (4096 + 24) #define CMDBUF_SIZE (4096 + 24)
#define DEFAULT_GAMMA 2.0 /***** Gamma different from 1.0 is potentially impacting color profile generation *****/
#define UNKNOWN_PID 0xffff #define UNKNOWN_PID 0xffff
#define CANON_VID 0x04a9 #define CANON_VID 0x04a9
@ -436,44 +435,47 @@ static int send_gamma_table (pixma_t * s)
const uint8_t *lut = s->param->gamma_table; const uint8_t *lut = s->param->gamma_table;
uint8_t *data; uint8_t *data;
if (mp->generation == 1) if (s->cfg->cap & PIXMA_CAP_GT_4096)
{ {
data = pixma_newcmd (&mp->cb, cmd_gamma, 4096 + 8, 0); data = pixma_newcmd (&mp->cb, cmd_gamma, 4096 + 8, 0);
data[0] = (s->param->channels == 3) ? 0x10 : 0x01; data[0] = (s->param->channels == 3) ? 0x10 : 0x01;
pixma_set_be16 (0x1004, data + 2); pixma_set_be16 (0x1004, data + 2);
if (lut) if (lut)
memcpy (data + 4, lut, 4096); {
/* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 4096 bytes from LUT ***** \n")); */
/* PDBG (pixma_hexdump (4, lut, 4096)); */
memcpy (data + 4, lut, 4096);
}
else else
pixma_fill_gamma_table (DEFAULT_GAMMA, data + 4, 4096); {
/* fallback: we should never see this */
PDBG (pixma_dbg (4, "*send_gamma_table***** Generate 4096 bytes Table with %f ***** \n",
s->param->gamma));
pixma_fill_gamma_table (s->param->gamma, data + 4, 4096);
/* PDBG (pixma_hexdump (4, data + 4, 4096)); */
}
} }
else else
{ {
/* FIXME: Gamma table for 2nd generation: 1024 * uint16_le */ /* Gamma table for 2nd+ generation: 1024 * uint16_le */
data = pixma_newcmd (&mp->cb, cmd_gamma, 2048 + 8, 0); data = pixma_newcmd (&mp->cb, cmd_gamma, 1024 * 2 + 8, 0);
data[0] = 0x10; data[0] = 0x10;
pixma_set_be16 (0x0804, data + 2); pixma_set_be16 (0x0804, data + 2);
if (lut) if (lut)
{ {
int i; /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); */
for (i = 0; i < 1024; i++) /* PDBG (pixma_hexdump (4, lut, 1024 * 2)); */
{ memcpy (data + 4, lut, 1024 * 2);
int j = (i << 2) + (i >> 8); }
data[4 + 2 * i + 0] = lut[j]; else
data[4 + 2 * i + 1] = lut[j]; {
} /* fallback: we should never see this */
PDBG (pixma_dbg (4, "*send_gamma_table***** Generate 1024 * 2 bytes Table with %f ***** \n",
s->param->gamma));
pixma_fill_gamma_table (s->param->gamma, data + 4, 1024);
/* PDBG (pixma_hexdump (4, data + 4, 1024 * 2)); */
}
} }
else
{
int i;
pixma_fill_gamma_table (DEFAULT_GAMMA, data + 4, 2048);
for (i = 0; i < 1024; i++)
{
int j = (i << 1) + (i >> 9);
data[4 + 2 * i + 0] = data[4 + j];
data[4 + 2 * i + 1] = data[4 + j];
}
}
}
return pixma_exec (s, &mp->cb); return pixma_exec (s, &mp->cb);
} }
@ -1869,8 +1871,8 @@ static int 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; unsigned w_max;
/* 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", /* PDBG (pixma_dbg (4, "*mp810_check_param***** Initially: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u, gamma=%f *****\n",
sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx)); */ sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx, sp->gamma)); */
sp->channels = 3; sp->channels = 3;
sp->software_lineart = 0; sp->software_lineart = 0;
@ -2396,9 +2398,9 @@ static const pixma_scan_ops_t pixma_mp800_ops =
const pixma_config_t pixma_mp800_devices[] = const pixma_config_t pixma_mp800_devices[] =
{ {
/* Generation 1: CCD */ /* Generation 1: CCD */
DEVICE ("Canon PIXMA MP800", "MP800", MP800_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), DEVICE ("Canon PIXMA MP800", "MP800", MP800_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_TPU | PIXMA_CAP_GT_4096),
DEVICE ("Canon PIXMA MP800R", "MP800R", MP800R_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), DEVICE ("Canon PIXMA MP800R", "MP800R", MP800R_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_TPU | PIXMA_CAP_GT_4096),
DEVICE ("Canon PIXMA MP830", "MP830", MP830_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_ADFDUP), DEVICE ("Canon PIXMA MP830", "MP830", MP830_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_ADFDUP | PIXMA_CAP_GT_4096),
/* Generation 2: CCD */ /* Generation 2: CCD */
DEVICE ("Canon PIXMA MP810", "MP810", MP810_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), DEVICE ("Canon PIXMA MP810", "MP810", MP810_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU),

Wyświetl plik

@ -1,6 +1,6 @@
/* Automatically generated from pixma_sane.c */ /* Automatically generated from pixma.c */
static const SANE_Range constraint_gamma_table = static const SANE_Range constraint_gamma_table =
{ 0,255,0 }; { 0,0xffff,0 };
static const SANE_Range constraint_gamma = static const SANE_Range constraint_gamma =
{ SANE_FIX(0.3),SANE_FIX(5),SANE_FIX(0) }; { SANE_FIX(0.3),SANE_FIX(5),SANE_FIX(0) };
static const SANE_Range constraint_threshold = static const SANE_Range constraint_threshold =
@ -123,17 +123,17 @@ int build_option_descriptors(struct pixma_sane_t *ss)
sod->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_AUTOMATIC|SANE_CAP_INACTIVE; sod->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_AUTOMATIC|SANE_CAP_INACTIVE;
sod->constraint_type = SANE_CONSTRAINT_NONE; sod->constraint_type = SANE_CONSTRAINT_NONE;
OPT_IN_CTX[opt_custom_gamma].info = 0; OPT_IN_CTX[opt_custom_gamma].info = 0;
opt->def.w = SANE_TRUE; opt->def.w = SANE_FALSE;
opt->val.w = SANE_TRUE; opt->val.w = SANE_FALSE;
opt = &(OPT_IN_CTX[opt_gamma_table]); opt = &(OPT_IN_CTX[opt_gamma_table]);
sod = &opt->sod; sod = &opt->sod;
sod->type = SANE_TYPE_INT; sod->type = SANE_TYPE_INT;
sod->title = SANE_TITLE_GAMMA_VECTOR; sod->title = SANE_TITLE_GAMMA_VECTOR;
sod->desc = SANE_DESC_GAMMA_VECTOR; sod->desc = SANE_I18N("Gamma-correction table with 1024 entries. In color mode this option equally affects the red, green, and blue channels simultaneously (i.e., it is an intensity gamma table).");
sod->name = "gamma-table"; sod->name = "gamma-table";
sod->unit = SANE_UNIT_NONE; sod->unit = SANE_UNIT_NONE;
sod->size = 4096 * sizeof(SANE_Word); sod->size = 1024 * sizeof(SANE_Word);
sod->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_AUTOMATIC|SANE_CAP_INACTIVE; sod->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_AUTOMATIC|SANE_CAP_INACTIVE;
sod->constraint_type = SANE_CONSTRAINT_RANGE; sod->constraint_type = SANE_CONSTRAINT_RANGE;
sod->constraint.range = &constraint_gamma_table; sod->constraint.range = &constraint_gamma_table;
@ -358,5 +358,4 @@ int build_option_descriptors(struct pixma_sane_t *ss)
opt->val.w = 0; opt->val.w = 0;
return 0; return 0;
} }

Wyświetl plik

@ -1,4 +1,4 @@
/* Automatically generated from pixma_sane.c */ /* Automatically generated from pixma.c */
typedef union { typedef union {
SANE_Word w; SANE_Word w;
@ -39,13 +39,11 @@ typedef enum {
opt_last opt_last
} option_t; } option_t;
typedef struct { typedef struct {
SANE_Option_Descriptor sod; SANE_Option_Descriptor sod;
option_value_t val,def; option_value_t val,def;
SANE_Word info; SANE_Word info;
} option_descriptor_t; } option_descriptor_t;
struct pixma_sane_t; struct pixma_sane_t;
static int build_option_descriptors(struct pixma_sane_t *ss); static int build_option_descriptors(struct pixma_sane_t *ss);

Wyświetl plik

@ -197,23 +197,20 @@ typedef union {
print ' ' + opt_prefix + 'last' print ' ' + opt_prefix + 'last'
print '} option_t;' print '} option_t;'
print """ print """
typedef struct { typedef struct {
SANE_Option_Descriptor sod; SANE_Option_Descriptor sod;
option_value_t val,def; option_value_t val,def;
SANE_Word info; SANE_Word info;
} option_descriptor_t; } option_descriptor_t;
struct pixma_sane_t; struct pixma_sane_t;
static int build_option_descriptors(struct pixma_sane_t *ss); static int build_option_descriptors(struct pixma_sane_t *ss);"""
"""
def genMinMaxRange(n, t, r): def genMinMaxRange(n, t, r):
if t == 'SANE_TYPE_FIXED': if t == 'SANE_TYPE_FIXED':
r = ['SANE_FIX(%s)' % x for x in r] r = ['SANE_FIX(%s)' % x for x in r]
print 'static const SANE_Range ' + n + ' = ' print 'static const SANE_Range ' + n + ' ='
print ' { ' + r[0] + ',' + r[1] + ',' + r[2] + ' };' print ' { ' + r[0] + ',' + r[1] + ',' + r[2] + ' };'
@ -371,9 +368,8 @@ int build_option_descriptors(struct pixma_sane_t *ss)
'%(full_code_default)s' '%(full_code_default)s'
sys.stdout.write(code % o) sys.stdout.write(code % o)
print print
print ' return 0;\n' print ' return 0;'
print '}' print '}'
print
g = Struct() g = Struct()
g.ngroups = 0 g.ngroups = 0
@ -381,7 +377,7 @@ opt_prefix = 'opt_'
con_prefix = 'constraint_' con_prefix = 'constraint_'
cnameMap = createCNameMap() cnameMap = createCNameMap()
options = parseFile(sys.stdin) options = parseFile(sys.stdin)
print "/* Automatically generated from pixma_sane.c */" print "/* Automatically generated from pixma.c */"
if (len(sys.argv) == 2) and (sys.argv[1] == 'h'): if (len(sys.argv) == 2) and (sys.argv[1] == 'h'):
genHeader(options) genHeader(options)
else: else: