Skip to content

Commit

Permalink
Merge pull request OSGeo#11136 from rouault/tiff_jxl_float_16
Browse files Browse the repository at this point in the history
TIFF JXL: add support for Float16 and Compression=52546 which is JPEG XL from DNG 1.7 specification
  • Loading branch information
rouault authored Oct 30, 2024
2 parents c0595f4 + 397ca15 commit 08cdbd2
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 7 deletions.
33 changes: 33 additions & 0 deletions autotest/gcore/tiff_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -9784,6 +9784,39 @@ def test_tiff_write_jpegxl_five_bands_lossless(tmp_vsimem):
assert ds.GetRasterBand(i + 1).Checksum() == 4672


###############################################################################


@pytest.mark.require_creation_option("GTiff", "JXL")
def test_tiff_write_jpegxl_float16(tmp_vsimem):

outfilename = str(tmp_vsimem / "test_tiff_write_jpegxl_float16")
src_ds = gdal.Open("data/float16.tif")
gdal.GetDriverByName("GTiff").CreateCopy(
outfilename, src_ds, options=["COMPRESS=JXL", "JXL_LOSSLESS=YES"]
)
ds = gdal.Open(outfilename)
assert ds.GetRasterBand(1).DataType == gdal.GDT_Float32
assert ds.GetRasterBand(1).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == "16"
assert ds.GetRasterBand(1).Checksum() == 4672


###############################################################################


@pytest.mark.require_creation_option("GTiff", "JXL")
@pytest.mark.parametrize("dt,nbits", [(gdal.GDT_Float64, None), (gdal.GDT_Byte, 1)])
@gdaltest.enable_exceptions()
def test_tiff_write_jpegxl_errors(tmp_vsimem, dt, nbits):

outfilename = str(tmp_vsimem / "test_tiff_write_jpegxl_errors")
with pytest.raises(Exception):
options = {"COMPRESS": "JXL"}
if nbits:
options["NBITS"] = str(nbits)
gdal.GetDriverByName("GTiff").Create(outfilename, 1, 1, 1, dt, options=options)


###############################################################################
# Test creating overviews with NaN nodata

Expand Down
7 changes: 7 additions & 0 deletions frmts/gtiff/geotiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,7 @@ static void GTiffTagExtender(TIFF *tif)
static std::mutex oDeleteMutex;
#ifdef HAVE_JXL
static TIFFCodec *pJXLCodec = nullptr;
static TIFFCodec *pJXLCodecDNG17 = nullptr;
#endif

void GTiffOneTimeInit()
Expand All @@ -1000,6 +1001,8 @@ void GTiffOneTimeInit()
if (pJXLCodec == nullptr)
{
pJXLCodec = TIFFRegisterCODEC(COMPRESSION_JXL, "JXL", TIFFInitJXL);
pJXLCodecDNG17 =
TIFFRegisterCODEC(COMPRESSION_JXL_DNG_1_7, "JXL", TIFFInitJXL);
}
#endif

Expand All @@ -1024,6 +1027,9 @@ static void GDALDeregister_GTiff(GDALDriver *)
if (pJXLCodec)
TIFFUnRegisterCODEC(pJXLCodec);
pJXLCodec = nullptr;
if (pJXLCodecDNG17)
TIFFUnRegisterCODEC(pJXLCodecDNG17);
pJXLCodecDNG17 = nullptr;
#endif
}

Expand Down Expand Up @@ -1058,6 +1064,7 @@ static const struct
{COMPRESSION_LERC, "LERC_ZSTD", true},
COMPRESSION_ENTRY(WEBP, true),
COMPRESSION_ENTRY(JXL, true),
COMPRESSION_ENTRY(JXL_DNG_1_7, true),

// Compression methods in read-only
COMPRESSION_ENTRY(OJPEG, false),
Expand Down
5 changes: 2 additions & 3 deletions frmts/gtiff/gtiffdataset_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5252,10 +5252,10 @@ TIFF *GTiffDataset::CreateLL(const char *pszFilename, int nXSize, int nYSize,
}

#ifdef HAVE_JXL
if (l_nCompression == COMPRESSION_JXL)
if (l_nCompression == COMPRESSION_JXL && eType != GDT_Float32)
{
// Reflects tif_jxl's GetJXLDataType()
if (eType != GDT_Byte && eType != GDT_UInt16 && eType != GDT_Float32)
if (eType != GDT_Byte && eType != GDT_UInt16)
{
ReportError(pszFilename, CE_Failure, CPLE_NotSupported,
"Data type %s not supported for JXL compression. Only "
Expand All @@ -5271,7 +5271,6 @@ TIFF *GTiffDataset::CreateLL(const char *pszFilename, int nXSize, int nYSize,
} asSupportedDTBitsPerSample[] = {
{GDT_Byte, 8},
{GDT_UInt16, 16},
{GDT_Float32, 32},
};

for (const auto &sSupportedDTBitsPerSample : asSupportedDTBitsPerSample)
Expand Down
1 change: 1 addition & 0 deletions frmts/gtiff/libtiff/tiff.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ typedef enum
#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */
#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */
#define COMPRESSION_JXL 50002 /* JPEGXL: WARNING not registered in Adobe-maintained registry */
#define COMPRESSION_JXL_DNG_1_7 52546 /* JPEGXL from DNG 1.7 specification */
#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */
#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */
#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */
Expand Down
21 changes: 17 additions & 4 deletions frmts/gtiff/tif_jxl.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,16 @@ static int GetJXLDataType(TIFF *tif)
return JXL_TYPE_FLOAT;
}

TIFFErrorExtR(tif, module,
"Unsupported combination of SampleFormat and BitsPerSample");
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
td->td_bitspersample == 16)
{
return JXL_TYPE_FLOAT16;
}

TIFFErrorExtR(
tif, module,
"Unsupported combination of SampleFormat(=%d) and BitsPerSample(=%d)",
td->td_sampleformat, td->td_bitspersample);
return -1;
}

Expand All @@ -113,6 +121,8 @@ static int GetJXLDataTypeSize(JxlDataType dtype)
return 2;
case JXL_TYPE_FLOAT:
return 4;
case JXL_TYPE_FLOAT16:
return 2;
default:
return 0;
}
Expand Down Expand Up @@ -811,7 +821,10 @@ static int JXLPostEncode(TIFF *tif)
basic_info.orientation = JXL_ORIENT_IDENTITY;
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
{
basic_info.exponent_bits_per_sample = 8;
if (td->td_bitspersample == 32)
basic_info.exponent_bits_per_sample = 8;
else
basic_info.exponent_bits_per_sample = 5;
}
else
{
Expand Down Expand Up @@ -1275,7 +1288,7 @@ int TIFFInitJXL(TIFF *tif, int scheme)
JXLState *sp;

(void)scheme;
assert(scheme == COMPRESSION_JXL);
assert(scheme == COMPRESSION_JXL || scheme == COMPRESSION_JXL_DNG_1_7);

/*
* Merge codec-specific tag information.
Expand Down
4 changes: 4 additions & 0 deletions frmts/gtiff/tif_jxl.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
50002 /* JPEGXL: WARNING not registered in Adobe-maintained registry */
#endif

#ifndef COMPRESSION_JXL_DNG_1_7
#define COMPRESSION_JXL_DNG_1_7 52546 /* JPEGXL from DNG 1.7 specification */
#endif

#ifndef TIFFTAG_JXL_LOSSYNESS

/* Pseudo tags */
Expand Down

0 comments on commit 08cdbd2

Please sign in to comment.