From 1751ed65721f74476ba8ccc2dbb7159c06516c6e Mon Sep 17 00:00:00 2001 From: Oliver Schwartz Date: Thu, 13 Oct 2005 22:43:30 +0000 Subject: [PATCH] Fixes for 16 bit scan mode from Simon Munton --- ChangeLog | 6 +++ backend/snapscan-options.c | 5 ++- backend/snapscan-scsi.c | 13 ++++++ backend/snapscan-sources.c | 5 +++ backend/snapscan.c | 89 +++++++++++++++++++++++++------------- 5 files changed, 87 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index e86ba3ad1..820a7aa7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-10-14 Oliver Schwartz + + * backend/snapscan-options.c backend/snapscan-scsi.c + backend/snapscan.c backend/snapscan-sources.c: + Fixes for 16 bit scan mode from Simon Munton + 2005-10-11 Oliver Schwartz * backend/snapscan-options.c backend/snapscan-scsi.c diff --git a/backend/snapscan-options.c b/backend/snapscan-options.c index 35d645a5c..c0127751b 100644 --- a/backend/snapscan-options.c +++ b/backend/snapscan-options.c @@ -183,7 +183,7 @@ static const SANE_Range gamma_range = }; static const SANE_Range gamma_vrange = { - 0, 255, 1 + 0, 65535, 1 }; static const SANE_Range lpr_range = { @@ -1585,6 +1585,9 @@ SANE_Status sane_control_option (SANE_Handle h, /* * $Log$ + * Revision 1.27 2005/10/13 22:43:30 oliver-guest + * Fixes for 16 bit scan mode from Simon Munton + * * Revision 1.26 2005/10/11 18:47:07 oliver-guest * Fixes for Epson 3490 and 16 bit scan mode * diff --git a/backend/snapscan-scsi.c b/backend/snapscan-scsi.c index 57e4c540e..3d31a270d 100644 --- a/backend/snapscan-scsi.c +++ b/backend/snapscan-scsi.c @@ -650,6 +650,10 @@ static void release_unit (SnapScan_Scanner *pss) #define DTCQ_GAMMA_RED14 0x96 #define DTCQ_GAMMA_GREEN14 0x97 #define DTCQ_GAMMA_BLUE14 0x98 +#define DTCQ_GAMMA_GRAY14_16BIT 0xa5 /* ? */ +#define DTCQ_GAMMA_RED14_16BIT 0xa6 +#define DTCQ_GAMMA_GREEN14_16BIT 0xa7 +#define DTCQ_GAMMA_BLUE14_16BIT 0xa8 static SANE_Status send (SnapScan_Scanner *pss, u_char dtc, u_char dtcq) { @@ -705,6 +709,12 @@ static SANE_Status send (SnapScan_Scanner *pss, u_char dtc, u_char dtcq) case DTCQ_GAMMA_BLUE14: tl = 16384; break; + case DTCQ_GAMMA_GRAY14_16BIT: /* 14-bit tables with 16 bit data */ + case DTCQ_GAMMA_RED14_16BIT: + case DTCQ_GAMMA_GREEN14_16BIT: + case DTCQ_GAMMA_BLUE14_16BIT: + tl = 32768; + break; default: DBG (DL_MAJOR_ERROR, "%s: bad gamma data type qualifier 0x%x\n", me, dtcq); @@ -1435,6 +1445,9 @@ static SANE_Status download_firmware(SnapScan_Scanner * pss) /* * $Log$ + * Revision 1.42 2005/10/13 22:43:30 oliver-guest + * Fixes for 16 bit scan mode from Simon Munton + * * Revision 1.41 2005/10/11 18:47:07 oliver-guest * Fixes for Epson 3490 and 16 bit scan mode * diff --git a/backend/snapscan-sources.c b/backend/snapscan-sources.c index f2b6d9ea1..566532dbd 100644 --- a/backend/snapscan-sources.c +++ b/backend/snapscan-sources.c @@ -823,6 +823,8 @@ static SANE_Status Deinterlacer_init (Deinterlacer *pself, pself->ch_bytes_per_pixel = 1; else pself->ch_bytes_per_pixel = 3; + if (pss->bpp_scan == 16) + pself->ch_bytes_per_pixel *= 2; } } return status; @@ -1175,6 +1177,9 @@ static SANE_Status create_source_chain (SnapScan_Scanner *pss, /* * $Log$ + * Revision 1.14 2005/10/13 22:43:30 oliver-guest + * Fixes for 16 bit scan mode from Simon Munton + * * Revision 1.13 2005/10/11 18:47:07 oliver-guest * Fixes for Epson 3490 and 16 bit scan mode * diff --git a/backend/snapscan.c b/backend/snapscan.c index 1ea6a38d9..fab9b92d6 100644 --- a/backend/snapscan.c +++ b/backend/snapscan.c @@ -149,7 +149,7 @@ static SANE_Char password[SANE_MAX_PASSWORD_LEN]; /* function prototypes */ static void gamma_n (double gamma, int brightness, int contrast, - u_char *buf, int length); + u_char *buf, int length, int gamma_16bit); static void gamma_to_sane (int length, u_char *in, SANE_Int *out); static size_t max_string_size(SANE_String_Const strings[]); @@ -243,7 +243,7 @@ static SANE_Status init_gamma(SnapScan_Scanner * ps) { u_char *gamma; - gamma = (u_char*) malloc(ps->gamma_length * sizeof(u_char)); + gamma = (u_char*) malloc(ps->gamma_length * sizeof(u_char) * 2); if (!gamma) { @@ -251,16 +251,16 @@ static SANE_Status init_gamma(SnapScan_Scanner * ps) } /* Default tables */ - gamma_n (SANE_UNFIX(ps->gamma_gs), ps->bright, ps->contrast, gamma, ps->bpp); + gamma_n (SANE_UNFIX(ps->gamma_gs), ps->bright, ps->contrast, gamma, ps->bpp, 1); gamma_to_sane (ps->gamma_length, gamma, ps->gamma_table_gs); - gamma_n (SANE_UNFIX(ps->gamma_r), ps->bright, ps->contrast, gamma, ps->bpp); + gamma_n (SANE_UNFIX(ps->gamma_r), ps->bright, ps->contrast, gamma, ps->bpp, 1); gamma_to_sane (ps->gamma_length, gamma, ps->gamma_table_r); - gamma_n (SANE_UNFIX(ps->gamma_g), ps->bright, ps->contrast, gamma, ps->bpp); + gamma_n (SANE_UNFIX(ps->gamma_g), ps->bright, ps->contrast, gamma, ps->bpp, 1); gamma_to_sane (ps->gamma_length, gamma, ps->gamma_table_g); - gamma_n (SANE_UNFIX(ps->gamma_b), ps->bright, ps->contrast, gamma, ps->bpp); + gamma_n (SANE_UNFIX(ps->gamma_b), ps->bright, ps->contrast, gamma, ps->bpp, 1); gamma_to_sane (ps->gamma_length, gamma, ps->gamma_table_b); free (gamma); @@ -286,7 +286,7 @@ static size_t max_string_size (SANE_String_Const strings[]) /* gamma table computation */ static void gamma_n (double gamma, int brightness, int contrast, - u_char *buf, int bpp) + u_char *buf, int bpp, int gamma_16bit) { int i; double i_gamma = 1.0/gamma; @@ -299,23 +299,37 @@ static void gamma_n (double gamma, int brightness, int contrast, double val = (i - mid) * (1.0 + contrast / 100.0) + (1.0 + brightness / 100.0) * mid; val = LIMIT(val, 0, max); - buf[i] = - (u_char) LIMIT(255*pow ((double) val/max, i_gamma) + 0.5, 0, 255); + if (gamma_16bit) + { + int x = LIMIT(65535*pow ((double) val/max, i_gamma) + 0.5, 0, 65535); + + buf[2*i] = (u_char) x; + buf[2*i + 1] = (u_char) (x >> 8); + } + else + buf[i] = + (u_char) LIMIT(255*pow ((double) val/max, i_gamma) + 0.5, 0, 255); } } -static void gamma_from_sane (int length, SANE_Int *in, u_char *out) +static void gamma_from_sane (int length, SANE_Int *in, u_char *out, int gamma_16bit) { int i; for (i = 0; i < length; i++) - out[i] = (u_char) LIMIT(in[i], 0, 255); + if (gamma_16bit) + { + out[2*i] = (u_char) LIMIT(in[i], 0, 65535); + out[2*i + 1] = (u_char) (LIMIT(in[i], 0, 65535) >> 8); + } + else + out[i] = (u_char) LIMIT(in[i] / 256, 0, 255); } static void gamma_to_sane (int length, u_char *in, SANE_Int *out) { int i; for (i = 0; i < length; i++) - out[i] = in[i]; + out[i] = in[2*i] + 256 * in[2*i + 1]; } /* dispersed-dot dither matrices; this is discussed in Foley, Van Dam, @@ -1318,6 +1332,7 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss) int dtcq_gamma_red; int dtcq_gamma_green; int dtcq_gamma_blue; + int gamma_16bit = 0; DBG (DL_CALL_TRACE, "%s\n", me); switch (mode) @@ -1351,10 +1366,21 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss) dtcq_gamma_blue = DTCQ_GAMMA_BLUE10; break; case 14: - dtcq_gamma_gray = DTCQ_GAMMA_GRAY14; - dtcq_gamma_red = DTCQ_GAMMA_RED14; - dtcq_gamma_green = DTCQ_GAMMA_GREEN14; - dtcq_gamma_blue = DTCQ_GAMMA_BLUE14; + if (pss->bpp_scan == 16) + { + dtcq_gamma_gray = DTCQ_GAMMA_GRAY14_16BIT; + dtcq_gamma_red = DTCQ_GAMMA_RED14_16BIT; + dtcq_gamma_green = DTCQ_GAMMA_GREEN14_16BIT; + dtcq_gamma_blue = DTCQ_GAMMA_BLUE14_16BIT; + gamma_16bit = 1; + } + else + { + dtcq_gamma_gray = DTCQ_GAMMA_GRAY14; + dtcq_gamma_red = DTCQ_GAMMA_RED14; + dtcq_gamma_green = DTCQ_GAMMA_GREEN14; + dtcq_gamma_blue = DTCQ_GAMMA_BLUE14; + } break; default: dtcq_gamma_gray = DTCQ_GAMMA_GRAY8; @@ -1372,34 +1398,34 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss) { /* Use greyscale gamma for all rgb channels */ gamma_from_sane (pss->gamma_length, pss->gamma_table_gs, - pss->buf + SEND_LENGTH); + pss->buf + SEND_LENGTH, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_red); CHECK_STATUS (status, me, "send"); gamma_from_sane (pss->gamma_length, pss->gamma_table_gs, - pss->buf + SEND_LENGTH); + pss->buf + SEND_LENGTH, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_green); CHECK_STATUS (status, me, "send"); gamma_from_sane (pss->gamma_length, pss->gamma_table_gs, - pss->buf + SEND_LENGTH); + pss->buf + SEND_LENGTH, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_blue); CHECK_STATUS (status, me, "send"); } else { gamma_from_sane (pss->gamma_length, pss->gamma_table_r, - pss->buf + SEND_LENGTH); + pss->buf + SEND_LENGTH, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_red); CHECK_STATUS (status, me, "send"); gamma_from_sane (pss->gamma_length, pss->gamma_table_g, - pss->buf + SEND_LENGTH); + pss->buf + SEND_LENGTH, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_green); CHECK_STATUS (status, me, "send"); gamma_from_sane (pss->gamma_length, pss->gamma_table_b, - pss->buf + SEND_LENGTH); + pss->buf + SEND_LENGTH, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_blue); CHECK_STATUS (status, me, "send"); } @@ -1410,34 +1436,34 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss) { /* Use greyscale gamma for all rgb channels */ gamma_n (gamma_gs, pss->bright, pss->contrast, - pss->buf + SEND_LENGTH, pss->bpp); + pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_red); CHECK_STATUS (status, me, "send"); gamma_n (gamma_gs, pss->bright, pss->contrast, - pss->buf + SEND_LENGTH, pss->bpp); + pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_green); CHECK_STATUS (status, me, "send"); gamma_n (gamma_gs, pss->bright, pss->contrast, - pss->buf + SEND_LENGTH, pss->bpp); + pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_blue); CHECK_STATUS (status, me, "send"); } else { gamma_n (gamma_r, pss->bright, pss->contrast, - pss->buf + SEND_LENGTH, pss->bpp); + pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_red); CHECK_STATUS (status, me, "send"); gamma_n (gamma_g, pss->bright, pss->contrast, - pss->buf + SEND_LENGTH, pss->bpp); + pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_green); CHECK_STATUS (status, me, "send"); gamma_n (gamma_b, pss->bright, pss->contrast, - pss->buf + SEND_LENGTH, pss->bpp); + pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_blue); CHECK_STATUS (status, me, "send"); } @@ -1448,14 +1474,14 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss) if(pss->val[OPT_CUSTOM_GAMMA].b) { gamma_from_sane (pss->gamma_length, pss->gamma_table_gs, - pss->buf + SEND_LENGTH); + pss->buf + SEND_LENGTH, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_gray); CHECK_STATUS (status, me, "send"); } else { gamma_n (gamma_gs, pss->bright, pss->contrast, - pss->buf + SEND_LENGTH, pss->bpp); + pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit); status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_gray); CHECK_STATUS (status, me, "send"); } @@ -1877,6 +1903,9 @@ SANE_Status sane_get_select_fd (SANE_Handle h, SANE_Int * fd) /* * $Log$ + * Revision 1.54 2005/10/13 22:43:30 oliver-guest + * Fixes for 16 bit scan mode from Simon Munton + * * Revision 1.53 2005/10/11 18:47:07 oliver-guest * Fixes for Epson 3490 and 16 bit scan mode *