Skip to content

fix: QR scanning fails on LineageOS due to camera row stride mismatch#500

Merged
torlando-tech merged 1 commit intomainfrom
claude/fix-qr-lineageos-Y7sQN
Feb 21, 2026
Merged

fix: QR scanning fails on LineageOS due to camera row stride mismatch#500
torlando-tech merged 1 commit intomainfrom
claude/fix-qr-lineageos-Y7sQN

Conversation

@torlando-tech
Copy link
Copy Markdown
Owner

Use plane.rowStride instead of imageProxy.width as the dataWidth
parameter in PlanarYUVLuminanceSource. On some devices (e.g. Xperia 10 V
running LineageOS), the Y plane row stride includes alignment padding
bytes beyond the image width. Passing imageProxy.width caused every row
after the first to be misaligned, corrupting the image data and
preventing ZXing from detecting QR codes.

Also add TRY_HARDER decode hint for improved detection reliability, and
remove consumeWindowInsets so the bottom instruction card properly
respects navigation bar padding on devices with 3-button navigation.

Fixes #477

https://claude.ai/code/session_01CkWLdAGiEP6rpP5xnWMayW

Use plane.rowStride instead of imageProxy.width as the dataWidth
parameter in PlanarYUVLuminanceSource. On some devices (e.g. Xperia 10 V
running LineageOS), the Y plane row stride includes alignment padding
bytes beyond the image width. Passing imageProxy.width caused every row
after the first to be misaligned, corrupting the image data and
preventing ZXing from detecting QR codes.

Also add TRY_HARDER decode hint for improved detection reliability, and
remove consumeWindowInsets so the bottom instruction card properly
respects navigation bar padding on devices with 3-button navigation.

Fixes #477

https://claude.ai/code/session_01CkWLdAGiEP6rpP5xnWMayW
@sentry
Copy link
Copy Markdown
Contributor

sentry bot commented Feb 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 18, 2026

Greptile Summary

Fixes QR code scanning on devices where the camera Y plane row stride differs from the image width (e.g., Xperia 10 V on LineageOS). The core change passes plane.rowStride instead of imageProxy.width as the dataWidth parameter to ZXing's PlanarYUVLuminanceSource, preventing row misalignment that corrupted image data and blocked QR detection.

  • Row stride fix: Uses plane.rowStride as dataWidth in PlanarYUVLuminanceSource to correctly handle devices with alignment padding bytes in the Y plane buffer. This is the correct approach — dataWidth represents the byte stride between rows, not the logical image width.
  • TRY_HARDER hint: Adds DecodeHintType.TRY_HARDER to the ZXing reader hints for improved QR detection reliability at the cost of slightly more CPU per frame.
  • consumeWindowInsets removal: Removes .consumeWindowInsets(paddingValues) so that .navigationBarsPadding() on the bottom instruction card is not suppressed, fixing layout on devices with 3-button navigation.

Confidence Score: 4/5

  • This PR is safe to merge — it fixes a real device-specific QR scanning bug with a well-understood approach.
  • The row stride fix is the standard correct approach for handling Y plane padding in Android camera frames with ZXing. The TRY_HARDER hint is a safe additive change. The consumeWindowInsets removal is intentional and correctly motivated for the QR scanner's specific layout (Scaffold with only a topBar, where child content needs its own navigation bar padding). Score is 4 rather than 5 because the buffer size vs. dataWidth*dataHeight validation in PlanarYUVLuminanceSource could theoretically throw on devices where the last row lacks padding, though in practice Android camera buffers are sized to avoid this.
  • No files require special attention — the single changed file contains a well-documented, targeted fix.

Important Files Changed

Filename Overview
app/src/main/java/com/lxmf/messenger/ui/screens/QrScannerScreen.kt Core QR scanning fix: uses plane.rowStride as dataWidth for PlanarYUVLuminanceSource to handle devices with row padding. Adds TRY_HARDER hint and removes consumeWindowInsets for proper nav bar padding. All changes are well-motivated and correct.

Sequence Diagram

sequenceDiagram
    participant Camera as CameraX
    participant Analyzer as QrCodeAnalyzer
    participant ZXing as ZXing MultiFormatReader
    participant UI as QrScannerScreen

    Camera->>Analyzer: analyze(imageProxy)
    Analyzer->>Analyzer: Check scan cooldown
    Analyzer->>Analyzer: Get Y plane buffer
    Note over Analyzer: data = ByteArray(buffer.remaining())
    Analyzer->>Analyzer: Get plane.rowStride
    Note over Analyzer: rowStride may include<br/>padding bytes > width
    Analyzer->>ZXing: PlanarYUVLuminanceSource(data, rowStride, height, 0, 0, width, height, false)
    Note over ZXing: dataWidth = rowStride ensures<br/>correct row byte offsets
    ZXing->>ZXing: HybridBinarizer → BinaryBitmap
    ZXing->>ZXing: decode(bitmap) with TRY_HARDER
    alt QR code found
        ZXing-->>Analyzer: Result with text
        Analyzer->>UI: onQrCodeDetected(qrText)
    else No QR code
        ZXing-->>Analyzer: Exception (ignored)
    end
    Analyzer->>Analyzer: imageProxy.close()
Loading

Last reviewed commit: 208ae0f

@torlando-tech torlando-tech merged commit 3cb8bdd into main Feb 21, 2026
14 checks passed
@torlando-tech torlando-tech deleted the claude/fix-qr-lineageos-Y7sQN branch February 21, 2026 00:42
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.

QR Scanning doesn't work on LineageOS

2 participants