---------- Původní e-mail ---------- Od: Olaf Meeuwissen <[email protected]> Komu: [email protected] Datum: 23. 3. 2019 12:55:56 Předmět: Re: [sane-devel] support status "Hi Marco,
Sorry for the belated follow-up. [email protected] writes: > Hi, > > regarding those v700-v850: I was mainly interested whether it supports 16 bpc > / infrared / dual lens. Unfortunately, when it comes to flatbed scanning of > analog film stock, the competition is essentially non-existent. > > > Thanks for the help, though. Regarding V600, 16bpc works on win and mac with > their Epson Scan. Unfortunately, for GNU/Linux, they provide an extremely > simplistic and practically useless (for analog negative scanning) utility > they call Image Scan. > > I've tried scanning as pnm - didn't work: :-(( > $ SANE_DEBUG_DLL=3 scanimage --verbose --format=pnm --source 'Transparency > Unit' --depth 16 > test16bpcV2.pnm > [... snip ...] > > I've also tried setting SANE_DEBUG_EPKOWA=HEX to see, what comes out. (The > output is really long, I'm not sure if it'd be appropriate for a mailing > list to post it here in full, so I've rehosted it to https://gitlab.com/ > snippets/1832781(https://gitlab.com/snippets/1832781)) - which might indeed > suggest that the bit depth is a problem somehow. Based on that log, the *device* does claim to support 16 bits input and output but does not say whether that bit depth is supported for which of the flatbed or the transparency unit or both. Whatever that closed source module does when requesting 16 bits of output is ours to guess as well :-/ Trudging through the log ... depth gets set to 16 bits[1] (with a pile of other settings) and scanner reports that succeeded[2] [1]: https://gitlab.com/snippets/1832781#L3512 [2]: https://gitlab.com/snippets/1832781#L3515 The read-back of those settings[3] doesn't reflect what was claimed to have been set successfully. Somewhere in the back of my mind I vaguely remember that that result should not be trusted. Ignoring that. [3]: https://gitlab.com/snippets/1832781#L3528 Arriving at the final line[4] in the log [4]: https://gitlab.com/snippets/1832781#L3608 dip-obj.c:572: [epkowa][F] failed: require (8 == buf->ctx.depth) Urk! That looks like the driver does not support digital image processing (DIP) for 16 bits when applying color profiles. One possible fix is patching up dip_apply_color_profile to handle 16 bits/channel, another is avoiding the invocation of that function for your device and do any kind of colour correction by some other means (if necessary). > Also worth noting that Vuescan - proprietary paid scanning software, which > has a Linux version seems to support 16bpc just fine. I've just tried that > and while the result is watermarked, the tiff seems to be true 16bpc (and > not in a cheaty way). Where with "cheaty" you probably mean software-emulated ;-/ # Applying a color profile is done in software but the 16 bpc is not # emulated (AFAICS). That closed source module and the firmware are of # course still "emulation suspects". > Is there anything I can try to make the V600 work with16bpc? Also, since you > mentioned that V700+ uses completely different backend, does that one > support 16bpc? (I don't have access to those scanners so I can't try). Hope this helps, -- Olaf Meeuwissen, LPIC-2 FSF Associate Member since 2004-01-27 GnuPG key: F84A2DD9/B3C0 2F47 EA19 64F4 9F13 F43E B8A4 A88A F84A 2DD9 Support Free Software https://my.fsf.org/donate Join the Free Software Foundation https://my.fsf.org/join " Hello, thanks for looking into it. I've also noticed that line. In fact, if you look a few lines above in the same source file, you'll see: <code>/*! \todo Add support for 16 bit color values (#816). */</code> Which sure looks 'reassuring'. I almost gave up, but then I stumbled upon this git repo: https://github.com/hean01/iscan. Someone had the same exact problem five years ago, forked the original iscan and wrote a patch to support 16bpc scanning. So I played around with it a bit, used the fork to create a patch for the package in my distro and it actually worked! The scan no longer crashes and the output looks like true 16bpc. I can even use xsane to do the scanning. I've included the patch as I've formatted it (I haven't tried to build straight from the repo (there are some open issues there claiming the build somehow fails), I used a distro build system, which built just fine and without errors). If someone need a bit more info, here's the relevant forum thread: https:// bbs.archlinux.org/viewtopic.php?pid=1835448#p1835448 Patch: <code>--- backend/channel-usb.c +++ backend/channel-usb.c @@ -91,6 +91,7 @@ static ssize_t channel_usb_send (channel *, const void *, static ssize_t channel_usb_recv (channel *, void *, size_t, SANE_Status *); +static size_t channel_usb_max_request_size (const channel *); channel * channel_usb_ctor (channel *self, const char *dev_name, SANE_Status *status) @@ -119,7 +120,7 @@ channel_usb_ctor (channel *self, const char *dev_name, SANE_Status *status) self->send = channel_usb_send; self->recv = channel_usb_recv; - self->max_size = 128 * 1024; + self->max_request_size = channel_usb_max_request_size; return self; } @@ -265,9 +266,6 @@ channel_interpreter_ctor (channel *self, const char *dev_name, self->dtor = channel_interpreter_dtor; } } - - self->max_size = 32 * 1024; - return self; } @@ -283,3 +281,10 @@ channel_interpreter_dtor (channel *self) self->dtor = channel_dtor; return self->dtor (self); } + +static size_t +channel_usb_max_request_size (const channel *self) +{ + return (self->interpreter ? 32 : 128) * 1024; +} + --- backend/dip-obj.c +++ backend/dip-obj.c @@ -555,44 +555,70 @@ dip_change_GRB_to_RGB (const void *self, const buffer *buf) return; } -/*! \todo Add support for 16 bit color values (#816). - */ void dip_apply_color_profile (const void *self, const buffer *buf, const double profile[9]) { SANE_Int i; - SANE_Byte *r_buf, *g_buf, *b_buf; double red, grn, blu; - SANE_Byte *data; SANE_Int size; require (dip == self && buf && profile); - require (8 == buf->ctx.depth); + require (buf->ctx.depth == 8 || buf->ctx.depth == 16); if (SANE_FRAME_RGB != buf->ctx.format) return; - data = buf->ptr; - size = buf->end - buf->ptr; + if (buf->ctx.depth == 8) + { + SANE_Byte *r_buf, *g_buf, *b_buf; + SANE_Byte *data; + + data = buf->ptr; + size = buf->end - buf->ptr; - for (i = 0; i < size / 3; i++) + for (i = 0; i < size / 3; i++) + { + r_buf = data; + g_buf = data + 1; + b_buf = data + 2; + + red = + profile[0] * (*r_buf) + profile[1] * (*g_buf) + profile[2] * (*b_buf); + grn = + profile[3] * (*r_buf) + profile[4] * (*g_buf) + profile[5] * (*b_buf); + blu = + profile[6] * (*r_buf) + profile[7] * (*g_buf) + profile[8] * (*b_buf); + + *data++ = clamp (red, 0, 255); + *data++ = clamp (grn, 0, 255); + *data++ = clamp (blu, 0, 255); + } + } + else if (buf->ctx.depth == 16) { - r_buf = data; - g_buf = data + 1; - b_buf = data + 2; - - red = - profile[0] * (*r_buf) + profile[1] * (*g_buf) + profile[2] * (*b_buf); - grn = - profile[3] * (*r_buf) + profile[4] * (*g_buf) + profile[5] * (*b_buf); - blu = - profile[6] * (*r_buf) + profile[7] * (*g_buf) + profile[8] * (*b_buf); - - *data++ = clamp (red, 0, 255); - *data++ = clamp (grn, 0, 255); - *data++ = clamp (blu, 0, 255); + uint16_t *r_buf, *g_buf, *b_buf; + uint16_t *data; + + data = (uint16_t *)buf->ptr; + while(data < buf->end) + { + r_buf = data; + g_buf = data + 1; + b_buf = data + 2; + + red = + profile[0] * (*r_buf) + profile[1] * (*g_buf) + profile[2] * (*b_buf); + grn = + profile[3] * (*r_buf) + profile[4] * (*g_buf) + profile[5] * (*b_buf); + blu = + profile[6] * (*r_buf) + profile[7] * (*g_buf) + profile[8] * (*b_buf); + + *data++ = clamp (red, 0, 65535); + *data++ = clamp (grn, 0, 65535); + *data++ = clamp (blu, 0, 65535); + } } }</code> Regards, JonnyRobbie
-- sane-devel mailing list: [email protected] https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/sane-devel Unsubscribe: Send mail with subject "unsubscribe your_password" to [email protected]
