Skip to content

Commit

Permalink
Merge pull request #8846 from OSGeo/backport-8838-to-release/3.8
Browse files Browse the repository at this point in the history
[Backport release/3.8] COG: for JPEG compression, convert single band+alpha as single band JPEG + 1-bit mask band
  • Loading branch information
rouault authored Nov 28, 2023
2 parents 8ecb6d4 + 1bd0069 commit 06c629c
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 8 deletions.
21 changes: 21 additions & 0 deletions autotest/gcore/cog.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,27 @@ def my_cbk(pct, _, arg):
gdal.Unlink(directory)


###############################################################################
# Test creation from a single band + alpha dataset


@pytest.mark.require_creation_option("COG", "JPEG")
def test_cog_single_band_plus_alpha_jpeg_compression(tmp_vsimem):

filename = str(tmp_vsimem / "cog.tif")
src_ds = gdal.GetDriverByName("MEM").Create("", 1, 1, 2)
src_ds.GetRasterBand(2).SetColorInterpretation(gdal.GCI_AlphaBand)

ds = gdal.GetDriverByName("COG").CreateCopy(
filename,
src_ds,
options=["COMPRESS=JPEG"],
)

assert ds.RasterCount == 1
assert ds.GetRasterBand(1).GetMaskFlags() == gdal.GMF_PER_DATASET


###############################################################################
# Test creation of overviews with a different compression method

Expand Down
2 changes: 2 additions & 0 deletions doc/source/drivers/raster/cog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ General creation options
For the COG driver, JPEG compression for 3 or 4-band images automatically
selects the PHOTOMETRIC=YCBCR colorspace with a 4:2:2 subsampling of the Y,Cb,Cr
components.
For a input dataset (single-band or 3-band), plus an alpha band,
the alpha band will be converted as a 1-bit DEFLATE compressed mask.

* ``LZW``, ``DEFLATE`` and ``ZSTD`` compressions can be used with the PREDICTOR creation option.

Expand Down
27 changes: 19 additions & 8 deletions frmts/gtiff/cogdriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -889,20 +889,31 @@ GDALDataset *GDALCOGCreator::Create(const char *pszFilename,

CPLString osCompress = CSLFetchNameValueDef(papszOptions, "COMPRESS",
gbHasLZW ? "LZW" : "NONE");
if (EQUAL(osCompress, "JPEG") && poCurDS->GetRasterCount() == 4 &&
poCurDS->GetRasterBand(4)->GetColorInterpretation() == GCI_AlphaBand)
if (EQUAL(osCompress, "JPEG") &&
(poCurDS->GetRasterCount() == 2 || poCurDS->GetRasterCount() == 4) &&
poCurDS->GetRasterBand(poCurDS->GetRasterCount())
->GetColorInterpretation() == GCI_AlphaBand)
{
char **papszArg = nullptr;
papszArg = CSLAddString(papszArg, "-of");
papszArg = CSLAddString(papszArg, "VRT");
papszArg = CSLAddString(papszArg, "-b");
papszArg = CSLAddString(papszArg, "1");
papszArg = CSLAddString(papszArg, "-b");
papszArg = CSLAddString(papszArg, "2");
papszArg = CSLAddString(papszArg, "-b");
papszArg = CSLAddString(papszArg, "3");
papszArg = CSLAddString(papszArg, "-mask");
papszArg = CSLAddString(papszArg, "4");
if (poCurDS->GetRasterCount() == 2)
{
papszArg = CSLAddString(papszArg, "-mask");
papszArg = CSLAddString(papszArg, "2");
}
else
{
CPLAssert(poCurDS->GetRasterCount() == 4);
papszArg = CSLAddString(papszArg, "-b");
papszArg = CSLAddString(papszArg, "2");
papszArg = CSLAddString(papszArg, "-b");
papszArg = CSLAddString(papszArg, "3");
papszArg = CSLAddString(papszArg, "-mask");
papszArg = CSLAddString(papszArg, "4");
}
GDALTranslateOptions *psOptions =
GDALTranslateOptionsNew(papszArg, nullptr);
CSLDestroy(papszArg);
Expand Down

0 comments on commit 06c629c

Please sign in to comment.