@@ -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