Skip to content

Fix LS-40 USB reads after a split image line - #68

Closed
codethinki wants to merge 1 commit into
activexray:mainfrom
codethinki:codex/fix-ls40-usb-fragments
Closed

codethinki wants to merge 1 commit into
activexray:mainfrom
codethinki:codex/fix-ls40-usb-fragments

Conversation

@codethinki

Copy link
Copy Markdown

Scanning a mounted slide on a Nikon Coolscan IV ED / LS-40 with WinUSB fails during host metering, after the first successful 128 KiB image READ. This was reported with NegPy 0.62 using nkscan 0.12 and reproduced with the standalone CLI:

device sent 1536 bytes for a 1522-byte read, so the stream is out of step

read_data_in treats the first short USB transfer as the maximum size of every later transfer in that data phase. A SCSI READ can split an image line, so the first transfer of the next READ can be a partial line while later transfers contain full lines.

In the reported trace, the metering pass has 1,722-byte RGB lines. A 131,072-byte READ ends 200 bytes into a line, leaving 1,522 bytes at the start of the next READ. The reader then limits subsequent buffers to 1,522 bytes. transfer_in rounds that request to the endpoint's 64-byte packet size, allowing 1,536 bytes to arrive. Those extra bytes belong to the image, but the reader treats them as a stream synchronization failure.

The fix asks each USB read for all bytes remaining in the command's data phase. Short transfers can therefore vary in length, and surplus bytes are treated as padding only beyond the end of that phase. The existing command deadline and zero-length termination still apply. The obsolete Chunk::count path is removed.

Four tests cover the reported partial-line sequence with byte-for-byte payload preservation, final packet padding with the status phase left queued, zero-length termination, and propagation of a read error.

Validation:

  • cargo fmt --all --check.
  • cargo clippy --locked --all-targets --all-features -- --deny warnings (PyO3 configured for the Python 3.13 stable ABI extension).
  • cargo test --locked --features cli: 156 library tests, one CLI test, and one doctest passed. The two existing hardware tests remain ignored locally.
  • The partial-line regression fails if the first-fragment length cap is restored in a temporary control copy.
  • The Windows executable and Python extension built successfully against nkscan 0.12.0 and loaded in WinBoat Windows 11. This PR preserves that reader behavior, with comment cleanup and two additional tests.
  • The reporter confirmed the patched build successfully scans their mounted slides on the affected Windows/LS-40 setup.

AI assistance: OpenAI Codex produced the diagnosis, code, tests, and PR description. The reporter supplied the original scanner trace, tested the patched build on their scanner, and requested this submission after confirming the fix.

@codethinki

Copy link
Copy Markdown
Author

if you dont like the coding style etc review and request changes, I'll fix it.

@activexray

Copy link
Copy Markdown
Owner

Thanks, I'll take a look soon!

@activexray

Copy link
Copy Markdown
Owner

fixed in 0.13

@activexray activexray closed this Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants