Skip to content

Commit f327c16

Browse files
authored
Make GDAL sources produce premultiplied RGBA (#282)
1 parent 0fc62b1 commit f327c16

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

lib/source_gdal.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,11 @@ CreateWarpedVRT( GDALDatasetH hSrcDS,
465465
return hDstDS;
466466
}
467467

468+
#define PREMULTIPLY(out,color,alpha)\
469+
{\
470+
int temp = ((alpha) * (color)) + 0x80;\
471+
out =((temp + (temp >> 8)) >> 8);\
472+
}
468473

469474
/**
470475
* \private \memberof mapcache_source_gdal
@@ -478,6 +483,9 @@ void _mapcache_source_gdal_render_metatile(mapcache_context *ctx, mapcache_sourc
478483
GDALDatasetH hTmpDS = NULL;
479484
mapcache_buffer *data;
480485
unsigned char *rasterdata;
486+
unsigned char* rowptr;
487+
unsigned char** row_pointers;
488+
int i, j;
481489
CPLErr eErr;
482490
mapcache_pooled_connection *pc = NULL;
483491
int bands_bgra[] = { 3, 2, 1, 4 }; /* mapcache buffer order is BGRA */
@@ -587,9 +595,41 @@ void _mapcache_source_gdal_render_metatile(mapcache_context *ctx, mapcache_sourc
587595
map->raw_image->w = map->width;
588596
map->raw_image->h = map->height;
589597
map->raw_image->stride = map->width * 4;
590-
map->raw_image->data = rasterdata;
591598
map->raw_image->has_alpha = MC_ALPHA_UNKNOWN;
592599

600+
// Handling of premulitiplication for GDAL sources.
601+
// Since the data is already in BGRA order, there is no need to swap the bytes around.
602+
603+
row_pointers = malloc(map->raw_image->h * sizeof(unsigned char*));
604+
apr_pool_cleanup_register(ctx->pool, row_pointers, (void*)free, apr_pool_cleanup_null);
605+
606+
rowptr = rasterdata;
607+
for(i = 0; i < map->raw_image->h; i++) {
608+
row_pointers[i] = rowptr;
609+
rowptr += map->raw_image->stride;
610+
}
611+
612+
for(i = 0; i < map->raw_image->h; i++) {
613+
unsigned char pixel[4];
614+
unsigned char alpha;
615+
unsigned char* pixptr = row_pointers[i];
616+
for(j = 0; j < map->raw_image->w; j++) {
617+
memcpy(pixel, pixptr, sizeof(unsigned int));
618+
alpha = pixel[3];
619+
if(alpha == 0) {
620+
pixptr[0] = 0;
621+
pixptr[1] = 0;
622+
pixptr[2] = 0;
623+
} else if (alpha < 255) {
624+
PREMULTIPLY(pixptr[0], pixel[0], alpha);
625+
PREMULTIPLY(pixptr[1], pixel[1], alpha);
626+
PREMULTIPLY(pixptr[2], pixel[2], alpha);
627+
}
628+
pixptr += 4;
629+
}
630+
}
631+
632+
map->raw_image->data = rasterdata;
593633
GDALClose( hDstDS ); /* close first this one, as it references hTmpDS or hSrcDS */
594634
if( hTmpDS )
595635
GDALClose(hTmpDS); /* references hSrcDS, so close before */

0 commit comments

Comments
 (0)