[sane-devel] support status

marcodv at seznam.cz marcodv at seznam.cz
Tue Mar 26 17:25:30 GMT 2019


---------- Původní e-mail ----------
Od: Olaf Meeuwissen <paddy-hack at member.fsf.org>
Komu: marcodv at seznam.cz
Datum: 23. 3. 2019 12:55:56
Předmět: Re: [sane-devel] support status 
"Hi Marco, 

Sorry for the belated follow-up. 

marcodv at seznam.cz 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



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/sane-devel/attachments/20190326/a2b38241/attachment.html>


More information about the sane-devel mailing list