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

Support loading TIFF subIFD's #2557

Closed
thany opened this issue Feb 2, 2021 · 5 comments
Closed

Support loading TIFF subIFD's #2557

thany opened this issue Feb 2, 2021 · 5 comments

Comments

@thany
Copy link

thany commented Feb 2, 2021

What are you trying to achieve?
I'm trying to load a DNG, and DNG's are saved in parts in TIFF subIFD's. Regardless, subIFD is part of the TIFF format, and there doesn't seem to be a way to specify a subIFD when loading a file/buffer, nor is there a way to know how many subIFD's a TIFF has.

Libvips appears to support this.

Also please note that subIFD is not the same as pages. The file I'm trying to read has 1 page, so the pages feature doesn't resolve this.

Also, I know very well that DNG isn't supported, but the issue is more general than that - subIFD is a TIFF standard, and DNG just happens to take advantage of it. Supporting this TIFF feature might be a step towards being able to read DNG with sharp - or at least decode the bits I need at a fairly awesome speed.

Have you searched for similar feature requests?
The word subIFD doesn't occur anywhere in this entire repo (well, it does now, but I mean before creating this issue).

What would you expect the API to look like?
Could be a property subIFDs: Array<Buffer> in the metadata() object, each of which can be passed back into a sharp() constructor. This would be in line with other metadata, which are also returned as binary blobs.

Another option would be to simply add subIFDs: number just to know how many there are. Then you could pass a subIFD index to the constructor like sharp('foo.dng', { subIFD: 2 }). This would be somewhat in line with the libvips API.

What alternatives have you considered?
A custom TIFF reader, but it's very slow and clunky. I'm sure lipvips can do much better.

Is there a sample image that helps explain?
Any ol' DNG will do, but I'll be happy to supply one, if need be.

@lovell
Copy link
Owner

lovell commented Feb 2, 2021

Hello, yes, libvips supports this feature so adding it to sharp should be fairly straightforward.

We'll need to expose the subifd property as an option on sharp's constructor and ensure it is set when loading TIFF images, in very much the same way that level is exposed for OpenSlide approximately here:

if (imageType == ImageType::OPENSLIDE) {

Happy to accept a PR for this, if you're able.

@thany
Copy link
Author

thany commented Feb 2, 2021

I think it wouldn't be too difficult to add an option in the constructor, but I have no clue (yet) how to go about having libvips return how many subIFD's there are in the first place. I haven't looked into that yet.

@jcupitt
Copy link
Contributor

jcupitt commented Feb 4, 2021

It's just like the n-pages property, so you should be able to copy-paste the code for that:

$ vips copy k2.jpg x.tif[pyramid,subifd]
$ vipsheader -a x.tif
x.tif: 1450x2048 uchar, 3 bands, srgb, tiffload
width: 1450
height: 2048
bands: 3
format: uchar
coding: none
interpretation: srgb
xoffset: 0
yoffset: 0
xres: 2.835
yres: 2.835
filename: x.tif
vips-loader: tiffload
n-subifds: 4
n-pages: 1
resolution-unit: in
orientation: 1

ie. five layers in this pyramid, with the main image as layer 0 and four subifds.

@lovell
Copy link
Owner

lovell commented Feb 4, 2021

Thanks John. For anyone looking to expose this subifds metadata in sharp, a good place to start is to follow the trail of existing code for the pages property returned by metadata, approximately here:

if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT) {

lovell added a commit that referenced this issue Apr 2, 2021
@lovell lovell added this to the v0.28.1 milestone Apr 2, 2021
@lovell
Copy link
Owner

lovell commented Apr 5, 2021

Commit 43a085d adds subifds to the metadata response and accepts an optional subifd via the constructor.

https://sharp.pixelplumbing.com/api-input#metadata
https://sharp.pixelplumbing.com/api-constructor#parameters

This is available in v0.28.1.

@lovell lovell closed this as completed Apr 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants