Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#125 broken odd page in ADF duplex mode with Fujitsu SnapScan

closed-wont-fix
nobody
None
5
2012-02-11
2012-02-07
Hiroshi Miura
No

It generate broken page in odd page in ADF duplex mode with Fujitsu(PFU) Snapscan S300.
An attachment is sample result.

This also resulted by scanadf-perl and scanimage-perl. With sane-utils scanimage produce good result.

Discussion

  • Hiroshi Miura
    Hiroshi Miura
    2012-02-07

     
    Attachments
  • Hiroshi Miura
    Hiroshi Miura
    2012-02-07

    This is caused by block size of sane_read().
    When I change it as folloows, problem is gone.

    --- gscan2pdf-1.0.0/bin/scanimage-perl 2010-02-23 01:29:23.000000000 +0900
    +++ gscan2pdf-1.0.0-1/bin/scanimage-perl 2012-02-07 23:45:25.372497671 +0900
    @@ -707,7 +707,7 @@
    * (($parm->{format} == SANE_FRAME_RGB || $parm->{format} == SANE_FRAME_GRAY) ? 1:3);

    while (1) {
    - my ($buffer, $len) = $device->read ($buffer_size);
    + my ($buffer, $len) = $device->read ($parm->{bytes_per_line});
    $total_bytes += $len;
    my $progr = (($total_bytes * 100.) / $hundred_percent);
    $progr = 100. if ($progr > 100.);

    --- gscan2pdf-1.0.0/lib/Gscan2pdf/Frontend/Sane.pm 2011-07-16 03:42:21.000000000 +0900
    +++ gscan2pdf-1.0.0-1/lib/Gscan2pdf/Frontend/Sane.pm 2012-02-07 23:49:50.224732798 +0900
    @@ -521,7 +521,7 @@

    while (1) {
    $device->cancel if ( $_self->{abort_scan} );
    - my ( $buffer, $len ) = $device->read($buffer_size);
    + my ( $buffer, $len ) = $device->read($parm->{bytes_per_line});
    $total_bytes += $len;
    my $progr = $total_bytes / $hundred_percent;
    $progr = 1 if ( $progr > 1 );

     
  • Hiroshi Miura
    Hiroshi Miura
    2012-02-11

    patch to detect problematic behavior and fix

     
    Attachments
  • Hiroshi Miura
    Hiroshi Miura
    2012-02-11

    Finally I can understand behaivor.

    Observing resulted pnm file, I can see problematic '\x78' or 'x' or 120.

    miurahr@tuna:~/Projects/sane$ od -t c test_data/debug_image_1.pnm |more
    0000000 P 4 \n # S A N E d a t a f
    0000020 o l l o w s \n \n 2 5 9 2 3 6 0
    0000040 0 \n \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    0000060 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    *
    0015260 \0 \0 \0 \0 \0 \0 x x x x x x x \0 \0 \0
    0015300 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    *
    0032520 \0 x x x x x x x \0 \0 \0 \0 \0 \0 \0 \0
    0032540 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    *
    0047740 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 x x x x
    0047760 x x x \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    0050000 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
    *
    0065200 \0 \0 \0 \0 \0 \0 \0 x x x x x x x \0 \0

    After then I modify gscan2pdf code to show behavior.

    --- ../orig/gscan2pdf-1.0.1/lib/Gscan2pdf/Frontend/Sane.pm 2012-01-14 04:43:37.000000000 +0900
    +++ lib/Gscan2pdf/Frontend/Sane.pm 2012-02-11 14:55:16.051893646 +0900
    @@ -577,7 +577,13 @@
    }
    }
    else { # ! must_buffer
    - print $fh $buffer;
    + if ( $len > 0 ) {
    + print $fh $buffer;
    + } else {
    + $logger->info(
    + sprintf "%s: WARNING: length is zero return by backend but buffer contains '%s' ",
    + $prog_name, $len, $buffer);
    + }
    }
    }
    $first_frame = 0;

    I can see below lines in a log.
    INFO - gscan2pdf: WARNING: length is zero return by backend but buffer contains 'x'
    INFO - gscan2pdf: WARNING: length is zero return by backend but buffer contains 'x'
    INFO - gscan2pdf: WARNING: length is zero return by backend but buffer contains 'x'
    INFO - gscan2pdf: WARNING: length is zero return by backend but buffer contains 'x'

    That it!

    A 'scanimage' resulted good output because it use length to output even when buffer has longer than length.
    but gscan2pdf just output $buffer, this makes

    INFO - gscan2pdf: scanning image of size 2592x3600 pixels at 1 bits/pixel
    INFO - gscan2pdf: acquiring gray frame
    INFO - gscan2pdf: read 1166400 bytes in total
    INFO - Scanned page /tmp/wFaOkjTinX/out1.pnm. (scanner status = 5)
    INFO - Importing scan with resolution=300
    INFO - Format is P4
    INFO - Header is 33
    INFO - gscan2pdf: acquiring gray frame
    INFO - Expecting 1166433, found 1167633
    INFO - New page filename /tmp/wFaOkjTinX/out1.pnm, format Portable anymap

    no needed 1200 bytes inside pnm file.

    Now there is a question, what part should be fixed?
    Because of SANE API standard, sane_read may return length 0. it is OK.

    in libsane-perl-0.03/Sane.xs:267
    void
    sane_read (handle, max_length)
    SANE_Handle handle
    SANE_Int max_length
    INIT:
    SANE_Status status;
    SANE_Byte * data;
    SANE_Int length;
    PPCODE:
    data = malloc (max_length);
    status = sane_read (handle, data, max_length, &length);
    SV* sv = get_sv("Sane::_status", FALSE);
    sv_setiv(sv, status);
    if (status) {
    XPUSHs(sv_2mortal(newSV(0)));
    XPUSHs(sv_2mortal(newSViv(0)));
    }
    else {
    XPUSHs(sv_2mortal(newSVpv(data, length)));
    XPUSHs(sv_2mortal(newSViv(length)));
    }
    free (data);

    ---------------------
    now newSVpv(data, length) is behave automatically to find the length of char when length=0.
    Bad.. when length is 0, data contains '120 0 0 248 100 127 0 0' in first 8 bytes in decimal.
    # this is observed by inserting debug code.
    120 in decimal is char 'x'

    Now you may be aware what happend.

    I'd like to propose 2 fixes for it.
    (1) we should be fix libsane-perl
    (2) we should gscan2pdf to be fail-safe.

    attached patch is good enough to escape this behavior even when libsane-perl not fixed.

     
  • Hiroshi Miura
    Hiroshi Miura
    2012-02-11

    • status: open --> closed-wont-fix