Skip to content

Commit 6e1a39f

Browse files
authored
Merge pull request #214 from jbo-ads/image-merge-optimization
Image merge optimization
2 parents 765ad96 + a3b2ad5 commit 6e1a39f

File tree

5 files changed

+48
-2
lines changed

5 files changed

+48
-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: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,43 @@ 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+
mapcache_image_alpha_type alpha_type;
66+
67+
switch (t) {
68+
case GC_JPEG:
69+
// JPEG files are opaque
70+
alpha_type = MC_ALPHA_NO;
71+
break;
72+
case GC_PNG:
73+
if (buffer->size >= 26) {
74+
// Check color type of PNG file in IHDR chunk
75+
if ( (b[12]|32)=='i' && (b[13]|32)=='h' && (b[14]|32)=='d' && (b[15]|32)=='r' ) {
76+
switch (b[25]) {
77+
case 4:
78+
case 6:
79+
// Gray or RGB with alpha
80+
alpha_type = MC_ALPHA_YES;
81+
break;
82+
default:
83+
// Other colortypes have no alpha channel
84+
alpha_type = MC_ALPHA_NO;
85+
}
86+
}
87+
} else {
88+
alpha_type = MC_ALPHA_UNKNOWN;
89+
}
90+
break;
91+
default:
92+
alpha_type = MC_ALPHA_UNKNOWN;
93+
break;
94+
}
95+
return alpha_type;
96+
}
97+
6198
mapcache_image* mapcache_imageio_decode(mapcache_context *ctx, mapcache_buffer *buffer)
6299
{
63100
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)