Fix GIF decoding for certain files
The handling is not perfect yet, but it should be fine enough.
This commit is contained in:
parent
231b77e6c0
commit
b973d323ba
16
fiv-io.c
16
fiv-io.c
@ -564,10 +564,17 @@ load_wuffs_frame(struct load_wuffs_frame_context *ctx, GError **error)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wuffs' test/data/animated-red-blue.gif, e.g., needs this handling.
|
||||||
|
cairo_format_t decode_format = ctx->cairo_format;
|
||||||
|
if (wuffs_base__frame_config__index(&fc) > 0 &&
|
||||||
|
wuffs_base__pixel_config__pixel_format(&ctx->cfg.pixcfg).repr ==
|
||||||
|
WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL)
|
||||||
|
decode_format = CAIRO_FORMAT_ARGB32;
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
unsigned char *targetbuf = NULL;
|
unsigned char *targetbuf = NULL;
|
||||||
cairo_surface_t *surface =
|
cairo_surface_t *surface =
|
||||||
cairo_image_surface_create(ctx->cairo_format, ctx->width, ctx->height);
|
cairo_image_surface_create(decode_format, ctx->width, ctx->height);
|
||||||
cairo_status_t surface_status = cairo_surface_status(surface);
|
cairo_status_t surface_status = cairo_surface_status(surface);
|
||||||
if (surface_status != CAIRO_STATUS_SUCCESS) {
|
if (surface_status != CAIRO_STATUS_SUCCESS) {
|
||||||
set_error(error, cairo_status_to_string(surface_status));
|
set_error(error, cairo_status_to_string(surface_status));
|
||||||
@ -659,6 +666,7 @@ load_wuffs_frame(struct load_wuffs_frame_context *ctx, GError **error)
|
|||||||
cairo_surface_mark_dirty(canvas);
|
cairo_surface_mark_dirty(canvas);
|
||||||
|
|
||||||
// Apply that frame's disposal method.
|
// Apply that frame's disposal method.
|
||||||
|
// XXX: We do not expect opaque pictures to receive holes this way.
|
||||||
wuffs_base__rect_ie_u32 bounds =
|
wuffs_base__rect_ie_u32 bounds =
|
||||||
wuffs_base__frame_config__bounds(&ctx->last_fc);
|
wuffs_base__frame_config__bounds(&ctx->last_fc);
|
||||||
// TODO(p): This field needs to be colour-managed.
|
// TODO(p): This field needs to be colour-managed.
|
||||||
@ -686,6 +694,8 @@ load_wuffs_frame(struct load_wuffs_frame_context *ctx, GError **error)
|
|||||||
// TODO(p): Implement, it seems tricky.
|
// TODO(p): Implement, it seems tricky.
|
||||||
// Might need another surface to keep track of the state.
|
// Might need another surface to keep track of the state.
|
||||||
break;
|
break;
|
||||||
|
case WUFFS_BASE__ANIMATION_DISPOSAL__NONE:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paint the current frame over that, within its bounds.
|
// Paint the current frame over that, within its bounds.
|
||||||
@ -844,8 +854,6 @@ open_wuffs(wuffs_base__image_decoder *dec, wuffs_base__io_buffer src,
|
|||||||
|
|
||||||
// Wuffs maps tRNS to BGRA in `decoder.decode_trns?`, we should be fine.
|
// Wuffs maps tRNS to BGRA in `decoder.decode_trns?`, we should be fine.
|
||||||
// wuffs_base__pixel_format__transparency() doesn't reflect the image file.
|
// wuffs_base__pixel_format__transparency() doesn't reflect the image file.
|
||||||
// TODO(p): See if wuffs_base__image_config__first_frame_is_opaque() causes
|
|
||||||
// issues with animations, and eventually ensure an alpha-capable format.
|
|
||||||
bool opaque = wuffs_base__image_config__first_frame_is_opaque(&ctx.cfg);
|
bool opaque = wuffs_base__image_config__first_frame_is_opaque(&ctx.cfg);
|
||||||
|
|
||||||
// Wuffs' API is kind of awful--we want to catch wide RGB and wide grey.
|
// Wuffs' API is kind of awful--we want to catch wide RGB and wide grey.
|
||||||
@ -886,6 +894,8 @@ open_wuffs(wuffs_base__image_decoder *dec, wuffs_base__io_buffer src,
|
|||||||
ctx.cairo_format = CAIRO_FORMAT_RGB30;
|
ctx.cairo_format = CAIRO_FORMAT_RGB30;
|
||||||
} else if (opaque) {
|
} else if (opaque) {
|
||||||
// BGRX doesn't have as wide swizzler support, namely in GIF.
|
// BGRX doesn't have as wide swizzler support, namely in GIF.
|
||||||
|
// Moreover, follower frames may still be partly transparent.
|
||||||
|
// Therefore, we choose to keep "wuffs_format" intact.
|
||||||
ctx.cairo_format = CAIRO_FORMAT_RGB24;
|
ctx.cairo_format = CAIRO_FORMAT_RGB24;
|
||||||
} else if (!ctx.target) {
|
} else if (!ctx.target) {
|
||||||
wuffs_format = WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL;
|
wuffs_format = WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL;
|
||||||
|
Loading…
Reference in New Issue
Block a user