[sane-devel] Scanning Lineart/Halftone with MICROTEK Scanmak

mh crapsite@gmx.net
Sun, 26 May 2002 19:06:53 +0200


Oliver Rauch, Sonntag, 26. Mai 2002 16:57:
> mh wrote:
> > after I could not find a bug in my backend, I dared to take a look at
> > xsane. I'm quite sure now, that there's indeed a bug in xsane. Please
> > take a look at the attached patch for xsane_scan.c.
> > I've tested this with the tevion, pnm and the test backend -> no
> > problems.
>
> Very strange. Your patch makes sense but I do not understand why it does
> work without the patch with the pnm backend.
>
> I have a more simple patch, please can you test it:
>
> -- fwrite(expanded_buf8, 1, len*8, xsane.out);
> ++ fwrite(expanded_buf8, 1, (size_t) (expanded_buf8ptr - expanded_buf8),
> xsane.out);

That works...
This is really a strange bug, but there's one difference between the pnm 
backend and e.g. the tevion backend:
When you "scan" a lineart image with the pnm backend, sane_read will allways 
return the number of bytes requested by the frontend (or the number of bytes 
left in the input file). This is normally more than one scanline, because 
xsane probably request 32 kB or something.
With the tevion backend (and probably other backends too), sane_read can 
return a number of bytes smaller or equal to the size of one scanline.
You can now modify the pnm backend in a way, that it returns one byte per 
call to sane_read, and voila, suddenly the bug also occurrs with the pnm 
backend :-)
This also reveals a small bug in the pnm backend, which will cause the 
frontend to hang in some rare cases.
See pnm.c around line 1162:

/* Suck in as much of the file as possible, since it's already in the
   correct format. */
  len = fread (data, 1, max_length, infile);

If fread returns 0, then *length is set to 0 and SANE_STATUS_GOOD is returned.
The frontend therefore expects more data, and calls sane_read again... -> 
infinite loop

We should replace this with

{
  /* Suck in as much of the file as possible, since it's already in the
     correct format. */
  len = fread (data, 1, max_length, infile);
  if(len <= 0)
    return SANE_STATUS_EOF;
}

If you want to reproduce the xsane bug with the pnm backend, just replace 
max_length with 1.

bb
Michael