From dc51819bbb844fedaa6f85a5891c3add4c4643ea Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 15 Oct 2024 16:28:15 +0200 Subject: [PATCH] Zarr V2 creation: fix bug when creating dataset with partial blocks and need to re-read them in the writing process when compression is involved Embarassingly, we were trying to decompress chunks with the ... compressor ... instead of the decompressor. Fixes #11016 --- autotest/gdrivers/zarr_driver.py | 22 ++++++++++++++++++++++ frmts/zarr/zarr_v2_group.cpp | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/autotest/gdrivers/zarr_driver.py b/autotest/gdrivers/zarr_driver.py index d2686208bd28..1bff911202a4 100644 --- a/autotest/gdrivers/zarr_driver.py +++ b/autotest/gdrivers/zarr_driver.py @@ -5523,3 +5523,25 @@ def test_zarr_read_cf1_zarrv3(): ds.GetSpatialRef().ExportToProj4() == "+proj=utm +zone=11 +ellps=clrk66 +units=m +no_defs" ) + + +############################################################################### +# Test bug fix for https://github.com/OSGeo/gdal/issues/11016 + + +@gdaltest.enable_exceptions() +@pytest.mark.require_driver("PNG") +def test_zarr_write_partial_blocks_compressed(tmp_vsimem): + + if "lz4" not in gdal.GetDriverByName("Zarr").GetMetadataItem("BLOSC_COMPRESSORS"): + pytest.skip("LZ4 compression missing") + + out_filename = "/vsimem/test.zarr" + src_ds = gdal.Open("data/png/rgba16.png") + gdal.Translate( + out_filename, + src_ds, + options="-of ZARR -co FORMAT=ZARR_V2 -co BLOCKSIZE=4,5,6 -co COMPRESS=LZ4 -co INTERLEAVE=BAND", + ) + out_ds = gdal.Open(out_filename) + assert out_ds.ReadRaster() == src_ds.ReadRaster() diff --git a/frmts/zarr/zarr_v2_group.cpp b/frmts/zarr/zarr_v2_group.cpp index 1bb2372c9faa..bef685a6bfb4 100644 --- a/frmts/zarr/zarr_v2_group.cpp +++ b/frmts/zarr/zarr_v2_group.cpp @@ -871,7 +871,7 @@ std::shared_ptr ZarrV2Group::CreateMDArray( if (!EQUAL(pszCompressor, "NONE")) { psCompressor = CPLGetCompressor(pszCompressor); - psDecompressor = CPLGetCompressor(pszCompressor); + psDecompressor = CPLGetDecompressor(pszCompressor); if (psCompressor == nullptr || psDecompressor == nullptr) { CPLError(CE_Failure, CPLE_NotSupported,