strukturag / libheif

libheif is an HEIF and AVIF file format decoder and encoder.
Other
1.71k stars 298 forks source link

Add initial TIFF decoder for heif-enc. #1205

Closed fancycode closed 2 months ago

fancycode commented 3 months ago

Requires libtiff-dev for building.

Basic support for RGB, RGBA both planar and contiguous. Unsupported files are detected and rejected. I tested with files from https://github.com/tlnagy/exampletiffs but would be happy if you have other testfiles.

fancycode commented 3 months ago

@farindk I updated the check for libtiff so it doesn't break if it's not available. With this, support for tiff is automatically detected and doesn't need to be explicitly enabled through a variable.

farindk commented 3 months ago

The intention of the option variable was to be able to disable it even though it is installed, e.g. to remove the dependency for packaging. But maybe it is not needed when the dependency is optional.

fancycode commented 3 months ago

For packaging you usually specify the build dependencies, so it won't be available if not specified there. With the option you would have to add libtiff-dev to the build dependencies and change the build command to pass the option.

This is unnecessarily redundant imho but if you rather want to have the explicit option I can add it again. I was going for the same way as PNG / JPEG support was added (i.e. autodetected without an option).

farindk commented 3 months ago

I think it is fine without the option.

farindk commented 2 months ago

@fancycode Do you think it is possible to read GeoTIFF files with libtiff? (https://github.com/cogeotiff/cog-spec/blob/203241975d054e5c933493f65bc4810e93d0048a/spec.md) These are basically TIFF files with image tiles and different resolution levels. If would be nice if we could convert those files to a HEIF format and maybe even copy over the compressed data from the GeoTIFF file without recompressing.

bradh commented 2 months ago

@farindk I think it is possible. Translating the metadata might be a fairly wide scope, but I see no reason why at least the imagery essence could not be moved for most of the common cases. Its definitely possible for uncompressed, without tiling.

There are cases where TIFF does things we can't represent in HEIF pyramids. Example:

Driver: GTiff/GeoTIFF
Files: /home/bradh/ACT2017-cog.tif
Size is 10000, 10000
Coordinate System is: (snipped)
Band 1 Block=512x512 Type=Byte, ColorInterp=Red
  Overviews: 5000x5000, 2500x2500, 1250x1250, 625x625, 312x312
Band 2 Block=512x512 Type=Byte, ColorInterp=Green
  Overviews: 5000x5000, 2500x2500, 1250x1250, 625x625, 312x312
Band 3 Block=512x512 Type=Byte, ColorInterp=Blue
  Overviews: 5000x5000, 2500x2500, 1250x1250, 625x625, 312x312

The only way we could do something like that would be to use thmb items.

farindk commented 2 months ago

There are cases where TIFF does things we can't represent in HEIF pyramids. Example:

I am not sure I understand what is shown in the example. To me, this looks like the TIFF file has three images (Band 1-3), separately for RGB and each of them is a pyramid. Why can't we do this with HEIF? I don't see what would keep us from storing three pyramids in the file.

bradh commented 2 months ago

Why can't we do this with HEIF? I don't see what would keep us from storing three pyramids in the file.

That would actually be one image with three bands as planar channels, plus five overview images.

My concern was that the overview images couldn't sensibly have the same tile sizes as the original image (i.e. 512 x 512). However now my jetlag has eased, I see it could - you'd just need to apply a crop (clap) for the unused part of the tile.

farindk commented 2 months ago

That would actually be one image with three bands as planar channels, plus five overview images.

Right, we cannot currently bundle separately coded RGB planes into one image. Except, maybe, for 23001-17. With other codecs, we can still code in the RGB colorspace combined into one image. I.e. we cannot extract only a single channel.

The problem is that there is currently no way to encode images with a custom set of channels other than attaching auxiliary channels to visual images. Maybe it boils down to using the GIMI ContentID, defined in the NGIIS meeting that you talked about, to assign content labels to the individual channels. I'm curious to see the details of that once it is made public. (see also the heif_channel enum in https://github.com/strukturag/libheif/pull/1211)

bradh commented 2 months ago

COG is typically uncompressed or DEFLATE. We can do the first with 23001-17 now, and we'll have DEFLATE soon.

We might also be able to do something with JPEG 2000.