-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow for intra-byte bits_per_sample. #218
base: master
Are you sure you want to change the base?
Conversation
Specifically, correctly read stripped tifs for any bits_per_sample sized up to the normal maximum bits_per_sample limit. Also, correctly read tiled tiffs that have bit padding in the last tile of each row. Bit padding in more than one tile per row is not supported. Future work could include error reporting about gaps in coverage, tests, and a separate newtype for buffer indexing (vs usize for bytes)
fn usize_div_ceil(numerator: usize, denominator: usize) -> usize { | ||
(numerator + denominator - 1) / denominator | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a comment here explaining what a "buffer unit" is? Though a shorter name might be better. Maybe call them "elements"?
if output_width == data_dims.0 as usize && padding_right == 0 { | ||
let total_samples = data_dims.0 as usize * data_dims.1 as usize * samples; | ||
let tile = &mut buffer.as_bytes_mut()[..total_samples * byte_len]; | ||
let row_buffer_units: usize = usize_div_ceil(data_dims.0 as usize * samples * self.bits_per_sample as usize, byte_len * 8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm nervous about overflowing a usize
here. I know the old code isn't careful here either, but it would be good to address. (Especially now that there's an additional multiplication by bits_per_sample that makes it even easier to overflow on a 32-bit system).
Probably the right thing to do would be to do most of the arithmetic using u64
's and then use try_into
when converting back.
/// If we leave in per-tile bit padding, then we cannot do it without knowing the number of tiles across this image is. | ||
/// | ||
/// We have two options basically for precise allocation without knowing the number of tiles across: | ||
/// * Ban tiles where tile_dim % (bits_per_sample * samples) == 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a check if this condition isn't met, and return an unsupported error in that case?
Specifically, correctly read stripped tifs for any bits_per_sample sized up to the normal maximum bits_per_sample limit. Also, correctly read tiled tiffs that have bit padding in the last tile of each row. Bit padding in more than one tile per row is not supported.
Future work could include error reporting about gaps in coverage, tests, and a separate newtype for buffer indexing (vs usize for bytes)
Addresses #217; here are the caveats/support:
(samples*bits_per_sample*tile_width)%byte_len
must be 0. Since tile dimensions are supposed to be multiples of 16, that means 1,2 and 4 bits_per_sample should always work. Other values may work correctly depending on the tile size and samples_per_pixel combination.