Fix R/B channel swap in Android raw pixel data#158
Open
mrousavy wants to merge 2 commits into
Open
Conversation
An ARGB_8888 Bitmap stores each pixel as a 32-bit word with R in the least significant byte (physically [R, G, B, A] bytes). The "ARGB" in the config name only refers to the getPixel/setPixel ColorInt packing (0xAARRGGBB), not the memory layout that copyPixelsFromBuffer and copyPixelsToBuffer read and write. The slow load path packed ColorInt-ordered words, and pixelFormat labeled ARGB_8888 exports as BGRA, so raw pixel data roundtrips swapped red and blue on little-endian devices. Pack the physical word instead, label exports as RGBA, and re-key the byte-identical raw-copy fast path to RGBA so BGRA input now goes through the corrected swizzle path. Also expose PixelFormat, RawPixelData, EncodedImageData and ImageFormat from the package entrypoint so consumers can read the reported format.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
On Android, an
ARGB_8888Bitmap's memory is physically[R, G, B, A]bytes. TheARGBin the config name only describes thegetPixel()/setPixel()ColorInt packing (0xAARRGGBB), not the layout thatcopyPixelsFromBuffer/copyPixelsToBuffer(raw memory copies) use.Two coupled bugs made every raw pixel roundtrip swap red and blue on little-endian devices:
loadFromRawPixelData(slow path) packed ColorInt-ordered words and wrote them withcopyPixelsFromBuffer, so on little-endian they landed asB, G, R, Abytes.toRawPixelDatalabeledARGB_8888exports asBGRA, but the raw-copied bytes are physicallyR, G, B, A.Fix
0xAABBGGRR) in the slow path.ARGB_8888exports asRGBA.BGRAtoRGBA, soBGRAinput now goes through the corrected swizzle path.PixelFormat,RawPixelData,EncodedImageDataandImageFormatfrom the entrypoint.Note for consumers
This is a behavior fix. Code that worked around the swap by mislabeling RGBA bytes as
'BGRA'on Android must drop that workaround (for example react-native-vision-camera's harness tests).Regression tests covering this land separately so they can validate all of the raw pixel data fixes together.
🤖 Generated with Claude Code