Skip to content

Commit

Permalink
Merge pull request #7069 from rouault/raster_gamma_correction
Browse files Browse the repository at this point in the history
GDAL/raster rendering: add a GAMMA processing option
  • Loading branch information
rouault committed Jun 13, 2024
2 parents dd96145 + 2ef337b commit 6a0a708
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 9 deletions.
Binary file added msautotest/gdal/expected/gamma_grayalpha.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added msautotest/gdal/expected/gamma_pct.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added msautotest/gdal/expected/gamma_rgb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added msautotest/gdal/expected/gamma_rgba.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions msautotest/gdal/gamma_grayalpha.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# Test GAMMA correction on a greyscale image with an alpha band
#
MAP

NAME TEST
STATUS ON
SIZE 400 300
EXTENT 0.5 0.5 399.5 299.5
IMAGECOLOR 255 255 0

IMAGETYPE png24_t

OUTPUTFORMAT
NAME png24_t
DRIVER "GDAL/PNG"
IMAGEMODE RGBA
END

LAYER
NAME test
TYPE raster
STATUS default
DATA data/greyalpha.vrt
PROCESSING "GAMMA=0.75"
END

END # of map file
22 changes: 22 additions & 0 deletions msautotest/gdal/gamma_pct.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#
# Test GAMMA correction on a image with a color table
#
MAP

NAME TEST
STATUS ON
SIZE 200 150
EXTENT 0.5 0.5 399.5 299.5
IMAGECOLOR 255 255 0

IMAGETYPE png24

LAYER
NAME test
TYPE raster
STATUS default
DATA data/pct22.tif
PROCESSING "GAMMA=0.75"
END

END # of map file
26 changes: 26 additions & 0 deletions msautotest/gdal/gamma_rgb.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#
# Test GAMMA correction on a RGB dataset
#
MAP

NAME TEST
STATUS ON
SIZE 400 300
EXTENT 0.5 0.5 399.5 299.5
IMAGECOLOR 255 255 0

IMAGETYPE png24

#
# Start of layer definitions
#

LAYER
NAME test
TYPE raster
STATUS default
DATA data/rgb.tif
PROCESSING "GAMMA=0.75"
END

END # of map file
33 changes: 33 additions & 0 deletions msautotest/gdal/gamma_rgba.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#
# Test GAMMA correction on a RGBA dataset
#
MAP

NAME TEST
STATUS ON
SIZE 400 300
EXTENT 0.5 0.5 399.5 299.5
IMAGECOLOR 255 255 0

IMAGETYPE png24_t

OUTPUTFORMAT
NAME png24_t
DRIVER "GDAL/PNG"
IMAGEMODE RGBA
TRANSPARENT ON
END

#
# Start of layer definitions
#

LAYER
NAME test
TYPE raster
STATUS default
DATA data/rgba.tif
PROCESSING "GAMMA=0.75"
END

END # of map file
56 changes: 47 additions & 9 deletions src/mapdrawgdal.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ static int msDrawRasterLayerGDAL_16BitClassification(
* rasterBufferObj setting macros.
*/

#define GAMMA_CORRECT(color, gamma) \
(int)(0.5 + 255 * pow((color) / 255.0, (gamma)))

/************************************************************************/
/* msDrawRasterLayerGDAL() */
/************************************************************************/
Expand Down Expand Up @@ -541,6 +544,9 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image,
return -1;
}

const char *sgamma = msLayerGetProcessingKey(layer, "GAMMA");
const double gamma = sgamma ? CPLAtof(sgamma) : 1.0;

/*
* Setup the mapping between source eight bit pixel values, and the
* output images color table. There are two general cases, where the
Expand Down Expand Up @@ -654,6 +660,12 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image,
rb_cmap[2][j] = pixel.blue;
rb_cmap[3][j] = 255;
}

if (gamma != 1.0) {
rb_cmap[0][j] = GAMMA_CORRECT(rb_cmap[0][j], gamma);
rb_cmap[1][j] = GAMMA_CORRECT(rb_cmap[1][j], gamma);
rb_cmap[2][j] = GAMMA_CORRECT(rb_cmap[2][j], gamma);
}
}
}
}
Expand Down Expand Up @@ -684,6 +696,11 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image,
rb_cmap[1][j] = sEntry.c2;
rb_cmap[2][j] = sEntry.c3;
rb_cmap[3][j] = sEntry.c4;
if (gamma != 1.0) {
rb_cmap[0][j] = GAMMA_CORRECT(rb_cmap[0][j], gamma);
rb_cmap[1][j] = GAMMA_CORRECT(rb_cmap[1][j], gamma);
rb_cmap[2][j] = GAMMA_CORRECT(rb_cmap[2][j], gamma);
}
}
}
}
Expand Down Expand Up @@ -825,21 +842,33 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image,
for (int j = dst_xoff; j < dst_xoff + dst_xsize; j++, k++) {
if (SKIP_MASK(j, i) || (pbIsNoDataBuffer && pbIsNoDataBuffer[k]))
continue;
if (MS_VALID_COLOR(layer->offsite) &&
pabyRaw1[k] == layer->offsite.red &&
pabyRaw2[k] == layer->offsite.green &&
pabyRaw3[k] == layer->offsite.blue)
int red = pabyRaw1[k];
int green = pabyRaw2[k];
int blue = pabyRaw3[k];
if (MS_VALID_COLOR(layer->offsite) && red == layer->offsite.red &&
green == layer->offsite.green && blue == layer->offsite.blue)
continue;

if (bHaveRGBNoData && pabyRaw1[k] == nNoData1 &&
pabyRaw2[k] == nNoData2 && pabyRaw3[k] == nNoData3)
if (bHaveRGBNoData && red == nNoData1 && green == nNoData2 &&
blue == nNoData3)
continue;

if (pabyRawAlpha == NULL || pabyRawAlpha[k] == 255) {
RB_SET_PIXEL(rb, j, i, pabyRaw1[k], pabyRaw2[k], pabyRaw3[k], 255);
if (gamma != 1.0) {
red = GAMMA_CORRECT(red, gamma);
green = GAMMA_CORRECT(green, gamma);
blue = GAMMA_CORRECT(blue, gamma);
}

RB_SET_PIXEL(rb, j, i, red, green, blue, 255);
} else if (pabyRawAlpha[k] != 0) {
RB_MIX_PIXEL(rb, j, i, pabyRaw1[k], pabyRaw2[k], pabyRaw3[k],
pabyRawAlpha[k]);
if (gamma != 1.0) {
red = GAMMA_CORRECT(red, gamma);
green = GAMMA_CORRECT(green, gamma);
blue = GAMMA_CORRECT(blue, gamma);
}

RB_MIX_PIXEL(rb, j, i, red, green, blue, pabyRawAlpha[k]);
}
}
}
Expand Down Expand Up @@ -2078,6 +2107,9 @@ static int msDrawRasterLayerGDAL_16BitClassification(
msGettimeofday(&starttime, NULL);
}

const char *sgamma = msLayerGetProcessingKey(layer, "GAMMA");
const double gamma = sgamma ? CPLAtof(sgamma) : 1.0;

lastC = -1;
for (i = 0; i < nBucketCount; i++) {
double dfOriginalValue;
Expand Down Expand Up @@ -2131,6 +2163,12 @@ static int msDrawRasterLayerGDAL_16BitClassification(
rb_cmap[2][i] = layer->class[c]->styles[styleindex]->color.blue;
rb_cmap[3][i] =
(255 * layer->class[c] -> styles[styleindex] -> opacity / 100);

if (gamma != 1.0) {
rb_cmap[0][i] = GAMMA_CORRECT(rb_cmap[0][i], gamma);
rb_cmap[1][i] = GAMMA_CORRECT(rb_cmap[1][i], gamma);
rb_cmap[2][i] = GAMMA_CORRECT(rb_cmap[2][i], gamma);
}
}
}
}
Expand Down

0 comments on commit 6a0a708

Please sign in to comment.