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;
|
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) {
|
WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
uint8_t* data = NULL;
|
uint8_t* data = NULL;
|
||||||
uint8_t* dst = NULL;
|
uint8_t* dst = NULL;
|
||||||
int num_frames;
|
|
||||||
int num_anim_chunks;
|
|
||||||
WebPMuxError err;
|
WebPMuxError err;
|
||||||
|
|
||||||
if (mux == NULL || assembled_data == NULL) {
|
if (mux == NULL || assembled_data == NULL) {
|
||||||
return WEBP_MUX_INVALID_ARGUMENT;
|
return WEBP_MUX_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove ANIM chunk if unnecessary.
|
// Finalize mux.
|
||||||
err = WebPMuxNumChunks(mux, kChunks[IDX_ANIM].id, &num_anim_chunks);
|
err = MuxCleanup(mux);
|
||||||
if (err != WEBP_MUX_OK) return err;
|
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);
|
err = CreateVP8XChunk(mux);
|
||||||
if (err != WEBP_MUX_OK) return err;
|
if (err != WEBP_MUX_OK) return err;
|
||||||
|
|
||||||
@ -641,7 +665,7 @@ WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
|
|||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize.
|
// Finalize data.
|
||||||
assembled_data->bytes = data;
|
assembled_data->bytes = data;
|
||||||
assembled_data->size = size;
|
assembled_data->size = size;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user