support for WebP is ready now (animation not supported)

This commit is contained in:
Vincent Wei
2021-10-20 16:22:26 +08:00
parent e2d2544ce6
commit 40f53732ff

View File

@@ -65,7 +65,7 @@
#define RIFF_HEADER_SIZE 12 #define RIFF_HEADER_SIZE 12
#define HEADER_CHUNK_SIZE 64 #define HEADER_CHUNK_SIZE 32
#define READ_BUFF_SIZE 1024 #define READ_BUFF_SIZE 1024
struct webp_decode_info { struct webp_decode_info {
@@ -161,6 +161,8 @@ void* __mg_init_webp(MG_RWops *fp, MYBITMAP *mybmp, RGB *pal)
pitch = ROUND_TO_MULTIPLE(pitch, 8); pitch = ROUND_TO_MULTIPLE(pitch, 8);
mybmp->pitch = pitch; mybmp->pitch = pitch;
info->config.output.width = info->config.input.width;
info->config.output.height = info->config.input.height;
return info; return info;
error: error:
@@ -174,7 +176,6 @@ void __mg_cleanup_webp(void *init_info)
struct webp_decode_info *info = init_info; struct webp_decode_info *info = init_info;
if (info) { if (info) {
free(info->config.output.u.RGBA.rgba);
free(info); free(info);
} }
} }
@@ -185,12 +186,20 @@ int __mg_load_webp(MG_RWops *fp, void *init_info, MYBITMAP *mybmp,
int rc = ERR_BMP_OK; int rc = ERR_BMP_OK;
struct webp_decode_info *info = init_info; struct webp_decode_info *info = init_info;
WebPIDecoder* idec = NULL; WebPIDecoder* idec = NULL;
int last_last_y = -1, last_y;
// Have config.output point to an external buffer: // Have config.output point to an external buffer:
info->config.output.u.RGBA.rgba = (uint8_t*)mybmp->bits;
info->config.output.u.RGBA.stride = mybmp->pitch;
info->config.output.u.RGBA.size = mybmp->pitch * mybmp->h;
info->config.output.is_external_memory = 1; info->config.output.is_external_memory = 1;
if (mybmp->flags & MYBMP_LOAD_ALLOCATE_ONE) {
info->config.output.u.RGBA.stride = mybmp->pitch;
info->config.output.u.RGBA.size = mybmp->pitch * mybmp->h;
mybmp->bits = realloc(mybmp->bits, info->config.output.u.RGBA.size);
}
else {
info->config.output.u.RGBA.stride = mybmp->pitch;
info->config.output.u.RGBA.size = mybmp->pitch * mybmp->h;
}
info->config.output.u.RGBA.rgba = (uint8_t*)mybmp->bits;
idec = WebPINewDecoder(&info->config.output); idec = WebPINewDecoder(&info->config.output);
if (idec == NULL) { if (idec == NULL) {
@@ -199,21 +208,27 @@ int __mg_load_webp(MG_RWops *fp, void *init_info, MYBITMAP *mybmp,
} }
while (1) { while (1) {
int last_last_y = -1, last_y;
int n; int n;
VP8StatusCode status = WebPIAppend(idec, info->data, info->sz_data); VP8StatusCode status = WebPIAppend(idec, info->data, info->sz_data);
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) {
_ERR_PRINTF ("__mg_load_webp: WebPIAppend failed: %d\n", status);
rc = ERR_BMP_LOAD; rc = ERR_BMP_LOAD;
break; break;
} }
if (WebPIDecGetRGB(idec, &last_y, NULL, NULL, NULL) && cb && if (WebPIDecGetRGB(idec, &last_y, NULL, NULL, NULL) &&
last_y > last_last_y) { (--last_y > last_last_y)) {
int y; int y;
for (y = last_last_y + 1; y <= last_y; y++) { for (y = last_last_y + 1; y <= last_y; y++) {
cb(context, mybmp, y); if (mybmp->flags & MYBMP_LOAD_ALLOCATE_ONE) {
mybmp->bits = info->config.output.u.RGBA.rgba;
mybmp->bits += mybmp->pitch * y;
}
if (cb)
cb(context, mybmp, y);
} }
last_last_y = last_y; last_last_y = last_y;
@@ -228,11 +243,14 @@ int __mg_load_webp(MG_RWops *fp, void *init_info, MYBITMAP *mybmp,
break; break;
} }
else { else {
_ERR_PRINTF ("__mg_load_webp: MGUI_RWread failed: %d\n", n);
rc = ERR_BMP_LOAD; rc = ERR_BMP_LOAD;
break; break;
} }
} }
mybmp->bits = info->config.output.u.RGBA.rgba;
ret: ret:
if (idec) if (idec)
WebPIDelete(idec); WebPIDelete(idec);