mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 04:18:26 +01:00
Add a simple cleanup step in mux assembly:
In particular, this removes any unnecessary FRGM/ANMF/ANIM chunks, and indirectly leads to removal of unnecessary VP8X chunks as well. This is especially useful for GIF to WebP conversion - it saves 56 bytes (ANMF: 16+8 bytes, ANIM: 6+8 bytes, VP8X: 10+8 bytes) for non-animated GIFs. Change-Id: I3b50a96ca585844c421b0fa4cd8593e52c3f95c5
This commit is contained in:
parent
51bb1e5de7
commit
74356eb558
@ -585,31 +585,55 @@ static WebPMuxError CreateVP8XChunk(WebPMux* const mux) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Cleans up 'mux' by removing any unnecessary chunks.
|
||||
static WebPMuxError MuxCleanup(WebPMux* const mux) {
|
||||
int num_frames;
|
||||
int num_fragments;
|
||||
int num_anim_chunks;
|
||||
|
||||
// If we have an image with single fragment or frame, convert it to a
|
||||
// non-animated non-fragmented image (to avoid writing FRGM/ANMF chunk
|
||||
// unnecessarily).
|
||||
WebPMuxError err = WebPMuxNumChunks(mux, kChunks[IDX_ANMF].id, &num_frames);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
err = WebPMuxNumChunks(mux, kChunks[IDX_FRGM].id, &num_fragments);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
if (num_frames == 1 || num_fragments == 1) {
|
||||
WebPMuxImage* frame_frag;
|
||||
err = MuxImageGetNth((const WebPMuxImage**)&mux->images_, 1, &frame_frag);
|
||||
assert(err == WEBP_MUX_OK); // We know that one frame/fragment does exist.
|
||||
if (frame_frag->header_ != NULL) {
|
||||
assert(frame_frag->header_->tag_ == kChunks[IDX_ANMF].tag ||
|
||||
frame_frag->header_->tag_ == kChunks[IDX_FRGM].tag);
|
||||
ChunkDelete(frame_frag->header_); // Removes ANMF/FRGM chunk.
|
||||
frame_frag->header_ = NULL;
|
||||
}
|
||||
num_frames = 0;
|
||||
num_fragments = 0;
|
||||
}
|
||||
// Remove ANIM chunk if this is a non-animated image.
|
||||
err = WebPMuxNumChunks(mux, kChunks[IDX_ANIM].id, &num_anim_chunks);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
if (num_anim_chunks >= 1 && num_frames == 0) {
|
||||
err = MuxDeleteAllNamedData(mux, kChunks[IDX_ANIM].tag);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
}
|
||||
return WEBP_MUX_OK;
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
|
||||
size_t size = 0;
|
||||
uint8_t* data = NULL;
|
||||
uint8_t* dst = NULL;
|
||||
int num_frames;
|
||||
int num_anim_chunks;
|
||||
WebPMuxError err;
|
||||
|
||||
if (mux == NULL || assembled_data == NULL) {
|
||||
return WEBP_MUX_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
// Remove ANIM chunk if unnecessary.
|
||||
err = WebPMuxNumChunks(mux, kChunks[IDX_ANIM].id, &num_anim_chunks);
|
||||
// Finalize mux.
|
||||
err = MuxCleanup(mux);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
if (num_anim_chunks >= 1) {
|
||||
err = WebPMuxNumChunks(mux, kChunks[IDX_ANMF].id, &num_frames);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
if (num_frames == 0) {
|
||||
err = MuxDeleteAllNamedData(mux, kChunks[IDX_ANIM].tag);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
}
|
||||
}
|
||||
|
||||
// Create VP8X chunk.
|
||||
err = CreateVP8XChunk(mux);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
|
||||
@ -641,7 +665,7 @@ WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
// Finalize.
|
||||
// Finalize data.
|
||||
assembled_data->bytes = data;
|
||||
assembled_data->size = size;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user