diff --git a/autotest/gdrivers/jp2kak.py b/autotest/gdrivers/jp2kak.py index 4b1c169ec291..63cc74f1fd39 100755 --- a/autotest/gdrivers/jp2kak.py +++ b/autotest/gdrivers/jp2kak.py @@ -456,6 +456,51 @@ def test_jp2kak_lossless_uint32_nbits_20(): gdal.GetDriverByName("JP2KAK").Delete(tmpfilename) +############################################################################### +# Test lossless copying of multi band with tiling (to cause a stripe_height != 1) + + +@pytest.mark.parametrize("use_stripe_compressor", ["YES", "NO"]) +def test_jp2kak_lossless_multiband(tmp_vsimem, use_stripe_compressor): + + src_ds = gdal.Open("data/rgbsmall.tif") + out_filename = str(tmp_vsimem / "out.jp2") + with gdaltest.config_option("JP2KAK_USE_STRIPE_COMPRESSOR", use_stripe_compressor): + gdal.GetDriverByName("JP2KAK").CreateCopy( + out_filename, + src_ds, + options=["QUALITY=100", "BLOCKXSIZE=32", "BLOCKYSIZE=24"], + ) + ds = gdal.Open(out_filename) + assert [ds.GetRasterBand(i + 1).Checksum() for i in range(3)] == [ + src_ds.GetRasterBand(i + 1).Checksum() for i in range(3) + ] + + +############################################################################### +# Test lossless copying of multi band with tiling (to cause a stripe_height != 1) + + +@pytest.mark.parametrize("use_stripe_compressor", ["YES", "NO"]) +def test_jp2kak_lossless_multiband_non_byte(tmp_vsimem, use_stripe_compressor): + + src_ds = gdal.Open("data/rgbsmall.tif") + src_ds = gdal.Translate( + "", src_ds, options="-f MEM -ot UInt16 -scale 0 255 0 65535" + ) + out_filename = str(tmp_vsimem / "out.jp2") + with gdaltest.config_option("JP2KAK_USE_STRIPE_COMPRESSOR", use_stripe_compressor): + gdal.GetDriverByName("JP2KAK").CreateCopy( + out_filename, + src_ds, + options=["QUALITY=100", "BLOCKXSIZE=32", "BLOCKYSIZE=24"], + ) + ds = gdal.Open(out_filename) + assert [ds.GetRasterBand(i + 1).Checksum() for i in range(3)] == [ + src_ds.GetRasterBand(i + 1).Checksum() for i in range(3) + ] + + ############################################################################### # Test lossy copying of Int32 diff --git a/frmts/jp2kak/jp2kakdataset.cpp b/frmts/jp2kak/jp2kakdataset.cpp index ad1e994ca9be..3ed7ab2fb72d 100644 --- a/frmts/jp2kak/jp2kakdataset.cpp +++ b/frmts/jp2kak/jp2kakdataset.cpp @@ -2903,7 +2903,9 @@ static GDALDataset *JP2KAKCreateCopy(const char *pszFilename, std::vector precisions(num_components); for (int i = 0; i < num_components; ++i) { - stripe_bufs[i] = pBuffer + nXSize * nDataTypeSizeBytes * i; + stripe_bufs[i] = pBuffer + static_cast(nXSize) * + nDataTypeSizeBytes * i * + stripe_height; is_signed[i] = CPL_TO_BOOL(GDALDataTypeIsSigned(eType)); precisions[i] = nBits; } @@ -2918,6 +2920,9 @@ static GDALDataset *JP2KAKCreateCopy(const char *pszFilename, for (int i = 0; i < num_components; ++i) { stripe_heights[i] = nHeight; + stripe_bufs[i] = pBuffer + static_cast(nXSize) * + nDataTypeSizeBytes * i * + nHeight; } } if (poSrcDS->RasterIO(GF_Read, 0, iY, nXSize, nHeight, pBuffer,