WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) { WebPMuxImage* next; if (wpi == NULL) return NULL; ChunkDelete(wpi->header_); ChunkDelete(wpi->alpha_); ChunkDelete(wpi->img_); next = wpi->next_; MuxImageInit(wpi); return next; }
// 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; }
// Cleans up 'mux' by removing any unnecessary chunks. static WebPMuxError MuxCleanup(WebPMux* const mux) { int num_frames; int num_anim_chunks; // If we have an image with a single frame, and its rectangle // covers the whole canvas, convert it to a non-animated image // (to avoid writing ANMF chunk unnecessarily). WebPMuxError err = WebPMuxNumChunks(mux, kChunks[IDX_ANMF].id, &num_frames); if (err != WEBP_MUX_OK) return err; if (num_frames == 1) { WebPMuxImage* frame = NULL; err = MuxImageGetNth((const WebPMuxImage**)&mux->images_, 1, &frame); assert(err == WEBP_MUX_OK); // We know that one frame does exist. assert(frame != NULL); if (frame->header_ != NULL && ((mux->canvas_width_ == 0 && mux->canvas_height_ == 0) || (frame->width_ == mux->canvas_width_ && frame->height_ == mux->canvas_height_))) { assert(frame->header_->tag_ == kChunks[IDX_ANMF].tag); ChunkDelete(frame->header_); // Removes ANMF chunk. frame->header_ = NULL; num_frames = 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; }
static WebPMuxError DeleteChunks(WebPChunk** chunk_list, uint32_t tag) { WebPMuxError err = WEBP_MUX_NOT_FOUND; assert(chunk_list); while (*chunk_list) { WebPChunk* const chunk = *chunk_list; if (chunk->tag_ == tag) { *chunk_list = ChunkDelete(chunk); err = WEBP_MUX_OK; } else { chunk_list = &chunk->next_; } } return err; }
int MuxImageFinalize(WebPMuxImage* const wpi) { const WebPChunk* const img = wpi->img_; const WebPData* const image = &img->data_; const int is_lossless = (img->tag_ == kChunks[IDX_VP8L].tag); int w, h; int vp8l_has_alpha = 0; const int ok = is_lossless ? VP8LGetInfo(image->bytes, image->size, &w, &h, &vp8l_has_alpha) : VP8GetInfo(image->bytes, image->size, image->size, &w, &h); assert(img != NULL); if (ok) { // Ignore ALPH chunk accompanying VP8L. if (is_lossless && (wpi->alpha_ != NULL)) { ChunkDelete(wpi->alpha_); wpi->alpha_ = NULL; } wpi->width_ = w; wpi->height_ = h; wpi->has_alpha_ = vp8l_has_alpha || (wpi->alpha_ != NULL); } return ok; }
void ChunkListDelete(WebPChunk** const chunk_list) { while (*chunk_list != NULL) { *chunk_list = ChunkDelete(*chunk_list); } }
static void DeleteAllChunks(WebPChunk** const chunk_list) { while (*chunk_list) { *chunk_list = ChunkDelete(*chunk_list); } }