Skip to content

Fix TY1 compression of unsigned integer images - #681

Merged
kif merged 1 commit into
silx-kit:mainfrom
aaronkanzer:fix/oxd-ty1-unsigned
Oct 28, 2026
Merged

kif merged 1 commit into
silx-kit:mainfrom
aaronkanzer:fix/oxd-ty1-unsigned

Conversation

@aaronkanzer

Copy link
Copy Markdown
Contributor

compTY1 computes the pixel differences with numpy.zeros_like(fdata), so they take the input dtype. With uint8, uint16 or uint32 data, any decrease from one pixel to the next wraps around and is stored as a large positive step. Every pixel after it is then off by 256, 65536, and so on. Unsigned input is common here: uint16 TIFF data, uint32 Eiger frames, and uint8 masks (the existing face.msk to OXD conversion test hits this path but only checks that the file exists).

import numpy, fabio
from fabio.OXDimage import OXDimage
data = numpy.array([[0, 37, 74, 9, 46]], dtype=numpy.uint8)
OXDimage(data=data).write("u8.img")
print(fabio.open("u8.img").data)

Observed on 2026.6.0 and main: [[ 0 37 74 265 302]]. Expected: [[ 0 37 74 9 46]].

int16 data with a full-range step (-32768 to 32767) also wraps for the same reason. The fix converts the input to int64 before computing the differences. The decoder already works in int64, so nothing changes on read.

compTY1 computed pixel differences in the input dtype, so any decrease
between neighbouring uint8/uint16/uint32 pixels wrapped around and was
stored as a large positive step. Compute the differences in int64.

@kif kif left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Thanks for the contribution.
LGTM

@kif
kif merged commit 1fca438 into silx-kit:main Oct 28, 2026
7 checks passed
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