From 24c016f40836dad746174711a7675833c8b9d278 Mon Sep 17 00:00:00 2001 From: Rolf Bensch Date: Sat, 30 May 2020 15:12:46 +0200 Subject: [PATCH 1/8] pixma_gen_options.py: fix print whitespace --- backend/pixma/scripts/pixma_gen_options.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/backend/pixma/scripts/pixma_gen_options.py b/backend/pixma/scripts/pixma_gen_options.py index c4c75e059..c12726727 100755 --- a/backend/pixma/scripts/pixma_gen_options.py +++ b/backend/pixma/scripts/pixma_gen_options.py @@ -197,23 +197,20 @@ typedef union { print ' ' + opt_prefix + 'last' print '} option_t;' print """ - typedef struct { SANE_Option_Descriptor sod; option_value_t val,def; SANE_Word info; } option_descriptor_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): if t == 'SANE_TYPE_FIXED': 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] + ' };' @@ -371,9 +368,8 @@ int build_option_descriptors(struct pixma_sane_t *ss) '%(full_code_default)s' sys.stdout.write(code % o) print - print ' return 0;\n' + print ' return 0;' print '}' - print g = Struct() g.ngroups = 0 @@ -381,7 +377,7 @@ opt_prefix = 'opt_' con_prefix = 'constraint_' cnameMap = createCNameMap() 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'): genHeader(options) else: From 103c77ddee320d38620dcbfe933fb341dc08a657 Mon Sep 17 00:00:00 2001 From: Rolf Bensch Date: Sat, 30 May 2020 15:26:20 +0200 Subject: [PATCH 2/8] new global variable for gamma get gamma value from 'opt_gamma' --- backend/pixma/pixma.c | 5 +++-- backend/pixma/pixma.h | 3 +++ backend/pixma/pixma_common.c | 2 +- backend/pixma/pixma_mp150.c | 4 ++-- backend/pixma/pixma_mp800.c | 4 ++-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/backend/pixma/pixma.c b/backend/pixma/pixma.c index aed9e7013..7bba261e7 100644 --- a/backend/pixma/pixma.c +++ b/backend/pixma/pixma.c @@ -827,8 +827,8 @@ print_scan_param (int level, const pixma_scan_param_t * sp) sp->line_size, sp->image_size, sp->channels, sp->depth); 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); - pixma_dbg (level, " gamma_table=%p source=%d\n", sp->gamma_table, - sp->source); + pixma_dbg (level, " gamma=%f gamma_table=%p source=%d\n", sp->gamma, + sp->gamma_table, sp->source); pixma_dbg (level, " adf-wait=%d\n", sp->adf_wait); } #endif @@ -873,6 +873,7 @@ calc_scan_param (pixma_sane_t * ss, pixma_scan_param_t * sp) sp->h = 1; sp->tpu_offset_added = 0; + sp->gamma = SANE_UNFIX (OVAL (opt_gamma).w); sp->gamma_table = (OVAL (opt_custom_gamma).b) ? ss->gamma_table : NULL; sp->source = ss->source_map[OVAL (opt_source).w]; sp->mode = ss->mode_map[OVAL (opt_mode).w]; diff --git a/backend/pixma/pixma.h b/backend/pixma/pixma.h index 7a417c031..4db0876c4 100644 --- a/backend/pixma/pixma.h +++ b/backend/pixma/pixma.h @@ -340,6 +340,9 @@ struct pixma_scan_param_t * specified by subdriver will be used. */ const uint8_t *gamma_table; + /** value for auto generated gamma table */ + double gamma; + /** \see #pixma_paper_source_t */ pixma_paper_source_t source; diff --git a/backend/pixma/pixma_common.c b/backend/pixma/pixma_common.c index 171df1a34..bb37923a2 100644 --- a/backend/pixma/pixma_common.c +++ b/backend/pixma/pixma_common.c @@ -880,7 +880,7 @@ pixma_scan (pixma_t * s, pixma_scan_param_t * sp) sp->line_size, sp->image_size, sp->channels, sp->depth); 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); - 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, " adf-wait=%d\n", sp->adf_wait); pixma_dbg (3, " ADF page count: %d\n", sp->adf_pageid); diff --git a/backend/pixma/pixma_mp150.c b/backend/pixma/pixma_mp150.c index ce2c33b8c..62155a5d1 100644 --- a/backend/pixma/pixma_mp150.c +++ b/backend/pixma/pixma_mp150.c @@ -1220,8 +1220,8 @@ mp150_check_param (pixma_t * s, pixma_scan_param_t * sp) { 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", - sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx)); */ + /* 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->gamma)); */ /* MP150 only supports 8 bit per channel in color and grayscale mode */ if (sp->depth != 1) diff --git a/backend/pixma/pixma_mp800.c b/backend/pixma/pixma_mp800.c index e050bc02d..5626b7517 100644 --- a/backend/pixma/pixma_mp800.c +++ b/backend/pixma/pixma_mp800.c @@ -1869,8 +1869,8 @@ static int mp810_check_param (pixma_t * s, pixma_scan_param_t * sp) mp810_t *mp = (mp810_t *) s->subdriver; 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", - sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx)); */ + /* 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->gamma)); */ sp->channels = 3; sp->software_lineart = 0; From 11126468ef880bf7f0ee6520247ac97ecdd59a9f Mon Sep 17 00:00:00 2001 From: Rolf Bensch Date: Sat, 30 May 2020 16:02:01 +0200 Subject: [PATCH 3/8] calculate 16-bit gamma table Generation 1 scanners need a 8-bit gamma table, with 4096 bytes size. All other scanners need a 16-bit gamma table, with 1024 bytes size. For these scanners values of the generated gamma table are close by the values used from the manufacturers proprietary driver. --- backend/pixma/pixma_common.c | 29 +++++++++++++++--- backend/pixma/pixma_mp150.c | 42 +++++++++++++------------- backend/pixma/pixma_mp800.c | 58 +++++++++++++++++++----------------- 3 files changed, 77 insertions(+), 52 deletions(-) diff --git a/backend/pixma/pixma_common.c b/backend/pixma/pixma_common.c index bb37923a2..2e03b6a20 100644 --- a/backend/pixma/pixma_common.c +++ b/backend/pixma/pixma_common.c @@ -1186,14 +1186,35 @@ pixma_get_config (pixma_t * s) void pixma_fill_gamma_table (double gamma, uint8_t * table, unsigned n) { - int i; + unsigned i; double r_gamma = 1.0 / gamma; - double out_scale = 255.0; 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); + } } } diff --git a/backend/pixma/pixma_mp150.c b/backend/pixma/pixma_mp150.c index 62155a5d1..d56c860fd 100644 --- a/backend/pixma/pixma_mp150.c +++ b/backend/pixma/pixma_mp150.c @@ -85,7 +85,6 @@ 4096 = size of gamma table. 24 = header + checksum */ #define IMAGE_BLOCK_SIZE (512*1024) #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 @@ -573,36 +572,39 @@ send_gamma_table (pixma_t * s) data[0] = (s->param->channels == 3) ? 0x10 : 0x01; pixma_set_be16 (0x1004, data + 2); 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 - 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 { - /* FIXME: Gamma table for 2nd generation: 1024 * uint16_le */ - data = pixma_newcmd (&mp->cb, cmd_gamma, 2048 + 8, 0); + /* Gamma table for 2nd+ generation: 1024 * uint16_le */ + data = pixma_newcmd (&mp->cb, cmd_gamma, 1024 * 2 + 8, 0); data[0] = 0x10; pixma_set_be16 (0x0804, data + 2); if (lut) { - int i; - for (i = 0; i < 1024; i++) - { - int j = (i << 2) + (i >> 8); - data[4 + 2 * i + 0] = lut[j]; - data[4 + 2 * i + 1] = lut[j]; - } + PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); + /* PDBG (pixma_hexdump (4, lut, 1024 * 2)); */ + memcpy (data + 4, lut, 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]; - } + /* fallback: we should never see this */ + PDBG (pixma_dbg (4, "*send_gamma_table***** Generate 1024 * 2 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)); */ } } return pixma_exec (s, &mp->cb); diff --git a/backend/pixma/pixma_mp800.c b/backend/pixma/pixma_mp800.c index 5626b7517..4791faf90 100644 --- a/backend/pixma/pixma_mp800.c +++ b/backend/pixma/pixma_mp800.c @@ -91,7 +91,6 @@ 4096 = size of gamma table. 24 = header + checksum */ #define IMAGE_BLOCK_SIZE (512*1024) #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 CANON_VID 0x04a9 @@ -442,38 +441,41 @@ static int send_gamma_table (pixma_t * s) data[0] = (s->param->channels == 3) ? 0x10 : 0x01; pixma_set_be16 (0x1004, data + 2); 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 - 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 { - /* FIXME: Gamma table for 2nd generation: 1024 * uint16_le */ - data = pixma_newcmd (&mp->cb, cmd_gamma, 2048 + 8, 0); - data[0] = 0x10; - pixma_set_be16 (0x0804, data + 2); - if (lut) - { - int i; - for (i = 0; i < 1024; i++) - { - int j = (i << 2) + (i >> 8); - data[4 + 2 * i + 0] = lut[j]; - data[4 + 2 * i + 1] = lut[j]; - } + /* Gamma table for 2nd+ generation: 1024 * uint16_le */ + data = pixma_newcmd (&mp->cb, cmd_gamma, 1024 * 2 + 8, 0); + data[0] = 0x10; + pixma_set_be16 (0x0804, data + 2); + if (lut) + { + PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); + /* PDBG (pixma_hexdump (4, lut, 1024 * 2)); */ + memcpy (data + 4, lut, 1024 * 2); + } + else + { + /* 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); } From 057aa02b34567ae51d828fdf9d054eec0aac1c58 Mon Sep 17 00:00:00 2001 From: Rolf Bensch Date: Sat, 30 May 2020 16:04:25 +0200 Subject: [PATCH 4/8] new capability for scanner generation 1 4096 bytes gamma table --- backend/pixma/pixma.h | 4 ++++ backend/pixma/pixma_mp150.c | 10 +++++----- backend/pixma/pixma_mp800.c | 6 +++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/backend/pixma/pixma.h b/backend/pixma/pixma.h index 4db0876c4..b27f81810 100644 --- a/backend/pixma/pixma.h +++ b/backend/pixma/pixma.h @@ -158,6 +158,10 @@ typedef uint32_t uint32_t; #define PIXMA_CAP_TPUIR ((1 << 11) | PIXMA_CAP_TPU) #define PIXMA_CAP_ADF_WAIT (1 << 12) #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) /**@}*/ diff --git a/backend/pixma/pixma_mp150.c b/backend/pixma/pixma_mp150.c index d56c860fd..61997f5c2 100644 --- a/backend/pixma/pixma_mp150.c +++ b/backend/pixma/pixma_mp150.c @@ -1614,11 +1614,11 @@ static const pixma_scan_ops_t pixma_mp150_ops = { const pixma_config_t pixma_mp150_devices[] = { /* Generation 1: CIS */ - DEVICE ("Canon PIXMA MP150", "MP150", MP150_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), - DEVICE ("Canon PIXMA MP450", "MP450", MP450_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), - DEVICE ("Canon PIXMA MP530", "MP530", MP530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + 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 | PIXMA_CAP_GT_4096), + 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 | PIXMA_CAP_GT_4096), + 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 */ DEVICE ("Canon PIXMA MP140", "MP140", MP140_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), diff --git a/backend/pixma/pixma_mp800.c b/backend/pixma/pixma_mp800.c index 4791faf90..5eb42f32e 100644 --- a/backend/pixma/pixma_mp800.c +++ b/backend/pixma/pixma_mp800.c @@ -2398,9 +2398,9 @@ static const pixma_scan_ops_t pixma_mp800_ops = const pixma_config_t pixma_mp800_devices[] = { /* Generation 1: CCD */ - DEVICE ("Canon PIXMA MP800", "MP800", MP800_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), - DEVICE ("Canon PIXMA MP830", "MP830", MP830_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_ADFDUP), + 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 | PIXMA_CAP_GT_4096), + DEVICE ("Canon PIXMA MP830", "MP830", MP830_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_ADFDUP | PIXMA_CAP_GT_4096), /* Generation 2: CCD */ DEVICE ("Canon PIXMA MP810", "MP810", MP810_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), From 16ff7c0bba68e9c39a90ab4394a1adcebcfa8adf Mon Sep 17 00:00:00 2001 From: Rolf Bensch Date: Sat, 30 May 2020 16:17:15 +0200 Subject: [PATCH 5/8] generate gamma table from control option we need to generate gamma table only once, after getting gamma from the frontend --- backend/pixma/pixma.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/backend/pixma/pixma.c b/backend/pixma/pixma.c index 7bba261e7..97c302f5b 100644 --- a/backend/pixma/pixma.c +++ b/backend/pixma/pixma.c @@ -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]); SANE_Word val; + /* PDBG (pixma_dbg (4, "*control_scalar_option***** n = %u, a = %u\n", n, a)); */ + switch (a) { 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; 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) { switch (a) @@ -750,10 +754,15 @@ control_option (pixma_sane_t * ss, SANE_Int n, case opt_gamma: if (a == SANE_ACTION_SET_VALUE || a == SANE_ACTION_SET_AUTO) { - /* PDBG (pixma_dbg (4, "*control_option***** gamma = %f *\n", - SANE_UNFIX (OVAL (opt_gamma).w))); */ + int table_size = SOD (opt_gamma_table).size / sizeof(SANE_Word); + 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", + SOD (opt_gamma_table).size / sizeof (SANE_Word))); 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; case opt_mode: @@ -874,7 +883,7 @@ calc_scan_param (pixma_sane_t * ss, pixma_scan_param_t * sp) sp->tpu_offset_added = 0; sp->gamma = SANE_UNFIX (OVAL (opt_gamma).w); - sp->gamma_table = (OVAL (opt_custom_gamma).b) ? ss->gamma_table : NULL; + sp->gamma_table = ss->gamma_table; sp->source = ss->source_map[OVAL (opt_source).w]; sp->mode = ss->mode_map[OVAL (opt_mode).w]; sp->adf_pageid = ss->page_count; @@ -899,6 +908,8 @@ init_option_descriptors (pixma_sane_t * ss) cfg = pixma_get_config (ss->s); + /* PDBG (pixma_dbg (4, "*init_option_descriptors*****\n")); */ + /* setup range for the scan area. */ ss->xrange.min = SANE_FIX (0); ss->xrange.max = SANE_FIX (cfg->width / 75.0 * 25.4); @@ -946,11 +957,14 @@ init_option_descriptors (pixma_sane_t * ss) /* Enable options that are available only in some scanners. */ if (cfg->cap & PIXMA_CAP_GAMMA_TABLE) { + /* activate option gamma */ 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); sane_control_option (ss, opt_custom_gamma, SANE_ACTION_SET_AUTO, - NULL, NULL); - pixma_fill_gamma_table (AUTO_GAMMA, ss->gamma_table, 4096); + NULL, NULL); } enable_option (ss, opt_button_controlled, ((cfg->cap & PIXMA_CAP_EVENTS) != 0)); From 16ddd3b9722f628ae82d7fb742718b54b2d6daa7 Mon Sep 17 00:00:00 2001 From: Rolf Bensch Date: Sat, 30 May 2020 16:21:05 +0200 Subject: [PATCH 6/8] get 1024 and 4096 size gamma tables from frontend Default gamma table has 1024 entries of 16 bits values. Only generation 1 scanners need a gamma table with 4096 entries of 8 bits values. --- backend/pixma/pixma.c | 105 ++++++++++++++++++++++------- backend/pixma/pixma_sane_options.c | 13 ++-- backend/pixma/pixma_sane_options.h | 4 +- 3 files changed, 88 insertions(+), 34 deletions(-) diff --git a/backend/pixma/pixma.c b/backend/pixma/pixma.c index 97c302f5b..6a8d24539 100644 --- a/backend/pixma/pixma.c +++ b/backend/pixma/pixma.c @@ -661,6 +661,7 @@ static SANE_Status control_option (pixma_sane_t * ss, SANE_Int n, SANE_Action a, void *v, SANE_Int * info) { + SANE_Option_Descriptor *sod = &SOD (n); int result, i; const pixma_config_t *cfg; SANE_Int dummy; @@ -678,25 +679,59 @@ control_option (pixma_sane_t * ss, SANE_Int n, switch (n) { case opt_gamma_table: - switch (a) - { - case SANE_ACTION_SET_VALUE: - clamp_value (ss, n, v, info); - for (i = 0; i != 4096; i++) - ss->gamma_table[i] = *((SANE_Int *) v + i); - break; - case SANE_ACTION_GET_VALUE: - for (i = 0; i != 4096; i++) - *((SANE_Int *) v + i) = ss->gamma_table[i]; - break; - case SANE_ACTION_SET_AUTO: - pixma_fill_gamma_table (AUTO_GAMMA, ss->gamma_table, - sizeof (ss->gamma_table)); - break; - default: - return SANE_STATUS_UNSUPPORTED; - } - return SANE_STATUS_GOOD; + { + int table_size = sod->size / sizeof (SANE_Word); + int byte_cnt = table_size == 1024 ? 2 : 1; + + switch (a) + { + case SANE_ACTION_SET_VALUE: + PDBG (pixma_dbg (4, "*control_option***** opt_gamma_table: SANE_ACTION_SET_VALUE with %d values ***** \n", table_size)); + clamp_value (ss, n, v, info); + if (byte_cnt == 1) + { + for (i = 0; i < table_size; i++) + ss->gamma_table[i] = *((SANE_Int *) v + i); + } + else + { + for (i = 0; i < table_size; i++) + { + 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: if (a == SANE_ACTION_SET_VALUE) @@ -749,6 +784,10 @@ control_option (pixma_sane_t * ss, SANE_Int n, { if (enable_option (ss, opt_gamma_table, OVAL (opt_custom_gamma).b)) *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; case opt_gamma: @@ -758,7 +797,7 @@ control_option (pixma_sane_t * ss, SANE_Int n, 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", - SOD (opt_gamma_table).size / sizeof (SANE_Word))); + (int)(SOD (opt_gamma_table).size / sizeof (SANE_Word)))); pixma_fill_gamma_table (SANE_UNFIX (OVAL (opt_gamma).w), ss->gamma_table, table_size); /* PDBG (pixma_hexdump (4, ss->gamma_table, @@ -957,6 +996,24 @@ init_option_descriptors (pixma_sane_t * ss) /* Enable options that are available only in some scanners. */ 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); sane_control_option (ss, opt_gamma, SANE_ACTION_SET_AUTO, @@ -2058,15 +2115,15 @@ type group title Gamma type bool custom-gamma - default SANE_TRUE + default SANE_FALSE title @SANE_TITLE_CUSTOM_GAMMA desc @SANE_DESC_CUSTOM_GAMMA cap soft_select soft_detect automatic inactive -type int gamma-table[4096] - constraint (0,255,0) +type int gamma-table[1024] + constraint (0,0xffff,0) 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 type fixed gamma diff --git a/backend/pixma/pixma_sane_options.c b/backend/pixma/pixma_sane_options.c index 2b8f60917..8264505bc 100644 --- a/backend/pixma/pixma_sane_options.c +++ b/backend/pixma/pixma_sane_options.c @@ -1,6 +1,6 @@ -/* Automatically generated from pixma_sane.c */ +/* Automatically generated from pixma.c */ static const SANE_Range constraint_gamma_table = - { 0,255,0 }; + { 0,0xffff,0 }; static const SANE_Range constraint_gamma = { SANE_FIX(0.3),SANE_FIX(5),SANE_FIX(0) }; 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->constraint_type = SANE_CONSTRAINT_NONE; OPT_IN_CTX[opt_custom_gamma].info = 0; - opt->def.w = SANE_TRUE; - opt->val.w = SANE_TRUE; + opt->def.w = SANE_FALSE; + opt->val.w = SANE_FALSE; opt = &(OPT_IN_CTX[opt_gamma_table]); sod = &opt->sod; sod->type = SANE_TYPE_INT; 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->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->constraint_type = SANE_CONSTRAINT_RANGE; sod->constraint.range = &constraint_gamma_table; @@ -358,5 +358,4 @@ int build_option_descriptors(struct pixma_sane_t *ss) opt->val.w = 0; return 0; - } diff --git a/backend/pixma/pixma_sane_options.h b/backend/pixma/pixma_sane_options.h index 1472f1f48..cb88686ac 100644 --- a/backend/pixma/pixma_sane_options.h +++ b/backend/pixma/pixma_sane_options.h @@ -1,4 +1,4 @@ -/* Automatically generated from pixma_sane.c */ +/* Automatically generated from pixma.c */ typedef union { SANE_Word w; @@ -39,13 +39,11 @@ typedef enum { opt_last } option_t; - typedef struct { SANE_Option_Descriptor sod; option_value_t val,def; SANE_Word info; } option_descriptor_t; - struct pixma_sane_t; static int build_option_descriptors(struct pixma_sane_t *ss); From 0118111c6fa935374800d1cf5cbb5f41d443712c Mon Sep 17 00:00:00 2001 From: Rolf Bensch Date: Fri, 5 Jun 2020 22:07:19 +0200 Subject: [PATCH 7/8] use capability to select gamma table size --- backend/pixma/pixma_mp150.c | 2 +- backend/pixma/pixma_mp800.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/pixma/pixma_mp150.c b/backend/pixma/pixma_mp150.c index 61997f5c2..159a8da93 100644 --- a/backend/pixma/pixma_mp150.c +++ b/backend/pixma/pixma_mp150.c @@ -566,7 +566,7 @@ send_gamma_table (pixma_t * s) const uint8_t *lut = s->param->gamma_table; 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[0] = (s->param->channels == 3) ? 0x10 : 0x01; diff --git a/backend/pixma/pixma_mp800.c b/backend/pixma/pixma_mp800.c index 5eb42f32e..8f315fac6 100644 --- a/backend/pixma/pixma_mp800.c +++ b/backend/pixma/pixma_mp800.c @@ -435,7 +435,7 @@ static int send_gamma_table (pixma_t * s) const uint8_t *lut = s->param->gamma_table; 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[0] = (s->param->channels == 3) ? 0x10 : 0x01; From 4b9dddb76365165070711e4b4f262a02dd9eefe1 Mon Sep 17 00:00:00 2001 From: Rolf Bensch Date: Fri, 5 Jun 2020 22:41:32 +0200 Subject: [PATCH 8/8] remove debug outputs from send gamma table --- backend/pixma/pixma_mp150.c | 4 ++-- backend/pixma/pixma_mp800.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/pixma/pixma_mp150.c b/backend/pixma/pixma_mp150.c index 159a8da93..616dd1bf8 100644 --- a/backend/pixma/pixma_mp150.c +++ b/backend/pixma/pixma_mp150.c @@ -573,7 +573,7 @@ send_gamma_table (pixma_t * s) pixma_set_be16 (0x1004, data + 2); if (lut) { - PDBG (pixma_dbg (4, "*send_gamma_table***** Use 4096 bytes from LUT ***** \n")); + /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 4096 bytes from LUT ***** \n")); */ /* PDBG (pixma_hexdump (4, lut, 4096)); */ memcpy (data + 4, lut, 4096); } @@ -594,7 +594,7 @@ send_gamma_table (pixma_t * s) pixma_set_be16 (0x0804, data + 2); if (lut) { - PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); + /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); */ /* PDBG (pixma_hexdump (4, lut, 1024 * 2)); */ memcpy (data + 4, lut, 1024 * 2); } diff --git a/backend/pixma/pixma_mp800.c b/backend/pixma/pixma_mp800.c index 8f315fac6..bac7cc42c 100644 --- a/backend/pixma/pixma_mp800.c +++ b/backend/pixma/pixma_mp800.c @@ -442,7 +442,7 @@ static int send_gamma_table (pixma_t * s) pixma_set_be16 (0x1004, data + 2); if (lut) { - PDBG (pixma_dbg (4, "*send_gamma_table***** Use 4096 bytes from LUT ***** \n")); + /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 4096 bytes from LUT ***** \n")); */ /* PDBG (pixma_hexdump (4, lut, 4096)); */ memcpy (data + 4, lut, 4096); } @@ -463,7 +463,7 @@ static int send_gamma_table (pixma_t * s) pixma_set_be16 (0x0804, data + 2); if (lut) { - PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); + /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); */ /* PDBG (pixma_hexdump (4, lut, 1024 * 2)); */ memcpy (data + 4, lut, 1024 * 2); }