Skip to content
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

Basic support for planar configuration #199

Merged
merged 2 commits into from
Jun 10, 2023
Merged

Conversation

pka
Copy link
Contributor

@pka pka commented Jan 12, 2023

Basic implementation for reading images in planar configuration.

Fixes #198.

Copy link
Contributor

@fintelia fintelia left a comment

Choose a reason for hiding this comment

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

This looks good to me. Could you also add handling for tiled planar images? I think it should just be a matter of updating the check at line 272 of src/decoder/image.rs.

src/decoder/image.rs Outdated Show resolved Hide resolved
@pka
Copy link
Contributor Author

pka commented Jan 17, 2023

This looks good to me. Could you also add handling for tiled planar images? I think it should just be a matter of updating the check at line 272 of src/decoder/image.rs.

I don't know how tiled planar images are organized. Are planes/bands row oriented or are they in every nth tile?

@HeroicKatora
Copy link
Member

HeroicKatora commented Feb 6, 2023

The best I can come up with is: it doesn't specify. https://web.archive.org/web/20210108174645/https://www.adobe.io/content/dam/udp/en/open/standards/tiff/TIFF6.pdf

Planar format. The components are stored in separate “component planes.” The
values in StripOffsets and StripByteCounts are then arranged as a 2-dimensional
array, with SamplesPerPixel rows and StripsPerImage columns. (All of the col-
umns for row 0 are stored first, followed by the columns of row 1, and so on.)
PhotometricInterpretation describes the type of data stored in each component
plane. For example, RGB data is stored with the Red components in one compo-
nent plane, the Green in another, and the Blue in another.

So: we can only recombine planes when PhotometricInterpretation is recognized, and only row-based encoding is mentioned. I can't find anything in imagemagick to indicate particular support for tile based images as well, but then again that decoding loop is somewhat obtuse C code to put it lightly.

@fintelia
Copy link
Contributor

fintelia commented Feb 6, 2023

The easiest strategy may be to generate a tiled planar TIFF using gdal_translate and see what the layout is

@@ -1155,7 +1162,12 @@ impl<R: Read + Seek> Decoder<R> {
let chunks_across = ((width - 1) / chunk_dimensions.0 + 1) as usize;
let strip_samples = width as usize * chunk_dimensions.1 as usize * samples;

for chunk in 0..self.image().chunk_offsets.len() {
let image_chunks = self.image().chunk_offsets.len() / self.image().strips_per_pixel();
Copy link
Member

Choose a reason for hiding this comment

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

This has caused me some headache. It seems improper to return partial data with no indication of it occurring. At that point, wouldn't users simply reach for manual chunk iteration anyways? I've been considering: the library is already choosing a layout for the usual case with no control given to the caller. Couldn't we just decide and document how to handle planar images, too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alternatively we could return no image, like now. The goal of this PR was extending the Decoder API to support planar-aware reading.

@pka
Copy link
Contributor Author

pka commented Feb 13, 2023

The best I can come up with is: it doesn't specify. https://web.archive.org/web/20210108174645/https://www.adobe.io/content/dam/udp/en/open/standards/tiff/TIFF6.pdf

Planar format. The components are stored in separate “component planes.” The
values in StripOffsets and StripByteCounts are then arranged as a 2-dimensional
array, with SamplesPerPixel rows and StripsPerImage columns. (All of the col-
umns for row 0 are stored first, followed by the columns of row 1, and so on.)
PhotometricInterpretation describes the type of data stored in each component
plane. For example, RGB data is stored with the Red components in one compo-
nent plane, the Green in another, and the Blue in another.

So: we can only recombine planes when PhotometricInterpretation is recognized, and only row-based encoding is mentioned. I can't find anything in imagemagick to indicate particular support for tile based images as well, but then again that decoding loop is somewhat obtuse C code to put it lightly.

Looks fine, seems like I was lucky.

@pka
Copy link
Contributor Author

pka commented Feb 13, 2023

The easiest strategy may be to generate a tiled planar TIFF using gdal_translate and see what the layout is

We could also ask @rouault for support.

Copy link
Contributor

@fintelia fintelia left a comment

Choose a reason for hiding this comment

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

I finally went and checked what gdal_translate does for tiled images. Turns out it outputs all the tiles for the first band, then all the tiles for the second band, and so on. This matches what the PR assumed, so I think this is set to go ahead and merge.

(Interestingly, gdal chose offsets for tiles that followed a different order: red channel of first tile, blue channel of first channel, etc. This doesn't impact decoding because TIFF has no guarantees on where in the file each chunk is in relation to the others)

@fintelia fintelia merged commit 473868a into image-rs:master Jun 10, 2023
@pka pka deleted the planar-config branch July 4, 2023 20:29
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.

InconsistentSizesEncountered error reading Tiff with planar config
3 participants