Skip to content

Commit c3f706d

Browse files
committed
Take PNG opacity into account when merging tiles
1 parent 765ad96 commit c3f706d

File tree

5 files changed

+35
-2
lines changed

5 files changed

+35
-2
lines changed

include/mapcache.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,6 +1534,11 @@ void _mapcache_imageio_jpeg_decode_to_image(mapcache_context *ctx, mapcache_buff
15341534
*/
15351535
mapcache_image_format_type mapcache_imageio_header_sniff(mapcache_context *ctx, mapcache_buffer *buffer);
15361536

1537+
/**
1538+
* \brief lookup the first few bytes of a buffer to check for alpha channel
1539+
*/
1540+
mapcache_image_alpha_type mapcache_imageio_alpha_sniff(mapcache_context *ctx, mapcache_buffer *buffer);
1541+
15371542
/**
15381543
* \brief checks if the given buffer is a recognized image format
15391544
*/

lib/imageio.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ mapcache_image_format_type mapcache_imageio_header_sniff(mapcache_context *ctx,
5858
}
5959
}
6060

61+
mapcache_image_alpha_type mapcache_imageio_alpha_sniff(mapcache_context *ctx, mapcache_buffer *buffer)
62+
{
63+
const unsigned char * b = buffer->buf;
64+
mapcache_image_format_type t = mapcache_imageio_header_sniff(ctx,buffer);
65+
if (t==GC_JPEG) {
66+
// A JPG file is opaque
67+
return MC_ALPHA_NO;
68+
} else if (t==GC_PNG && buffer->size >= 26 && (b[12]|32) == 'i' && (b[13]|32) == 'h' && (b[14]|32) == 'd' && (b[15]|32) == 'r') {
69+
// Check color type of PNG file in IHDR chunk
70+
if (b[25] == 0 || b[25] == 2) {
71+
// Gray or RGB without alpha
72+
return MC_ALPHA_NO;
73+
} else if (b[25] == 4 || b[25] == 6) {
74+
// Gray or RGB with alpha
75+
return MC_ALPHA_YES;
76+
} else {
77+
// TODO: Should check palette index
78+
return MC_ALPHA_UNKNOWN;
79+
}
80+
} else {
81+
return MC_ALPHA_UNKNOWN;
82+
}
83+
}
84+
6185
mapcache_image* mapcache_imageio_decode(mapcache_context *ctx, mapcache_buffer *buffer)
6286
{
6387
mapcache_image_format_type type = mapcache_imageio_header_sniff(ctx,buffer);

lib/imageio_jpeg.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ void _mapcache_imageio_jpeg_decode_to_image(mapcache_context *r, mapcache_buffer
243243
return;
244244
}
245245

246+
img->has_alpha = MC_ALPHA_NO;
246247
jpeg_read_header(&cinfo, TRUE);
247248
jpeg_start_decompress(&cinfo);
248249
img->w = cinfo.output_width;

lib/imageio_png.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ void _mapcache_imageio_png_decode_to_image(mapcache_context *ctx, mapcache_buffe
408408
unsigned char pixel[4];
409409
uint8_t alpha;
410410
unsigned char *pixptr = row_pointers[i];
411+
img->has_alpha = MC_ALPHA_NO;
411412
for(j=0; j<img->w; j++) {
412413

413414
memcpy (pixel, pixptr, sizeof (uint32_t));
@@ -417,10 +418,12 @@ void _mapcache_imageio_png_decode_to_image(mapcache_context *ctx, mapcache_buffe
417418
pixptr[1] = pixel[1];
418419
pixptr[2] = pixel[0];
419420
} else if (alpha == 0) {
421+
img->has_alpha = MC_ALPHA_YES;
420422
pixptr[0] = 0;
421423
pixptr[1] = 0;
422424
pixptr[2] = 0;
423425
} else {
426+
img->has_alpha = MC_ALPHA_YES;
424427
PREMULTIPLY(pixptr[0],pixel[2],alpha);
425428
PREMULTIPLY(pixptr[1],pixel[1],alpha);
426429
PREMULTIPLY(pixptr[2],pixel[0],alpha);

lib/tileset.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -903,8 +903,8 @@ void mapcache_tileset_tile_set_get_with_subdimensions(mapcache_context *ctx, map
903903
if(GC_HAS_ERROR(ctx))
904904
goto cleanup;
905905
}
906-
if((subtile->encoded_data && mapcache_imageio_header_sniff(ctx,subtile->encoded_data) == GC_JPEG)||
907-
(subtile->raw_image && subtile->raw_image->has_alpha == MC_ALPHA_NO)) {
906+
if ((mapcache_imageio_alpha_sniff(ctx,subtile->encoded_data) == MC_ALPHA_NO) ||
907+
(subtile->raw_image && subtile->raw_image->has_alpha == MC_ALPHA_NO)) {
908908
/* the returned image is fully opaque, we don't need to get/decode/merge any further subtiles */
909909
if(assembled_image)
910910
assembled_image->has_alpha = MC_ALPHA_NO;

0 commit comments

Comments
 (0)