in Extended/libwebp/src/mux/muxinternal.c [456:543]
WebPMuxError MuxValidate(const WebPMux* const mux) {
int num_iccp;
int num_exif;
int num_xmp;
int num_anim;
int num_frames;
int num_vp8x;
int num_images;
int num_alpha;
uint32_t flags;
WebPMuxError err;
// Verify mux is not NULL.
if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
// Verify mux has at least one image.
if (mux->images_ == NULL) return WEBP_MUX_INVALID_ARGUMENT;
err = WebPMuxGetFeatures(mux, &flags);
if (err != WEBP_MUX_OK) return err;
// At most one color profile chunk.
err = ValidateChunk(mux, IDX_ICCP, ICCP_FLAG, flags, 1, &num_iccp);
if (err != WEBP_MUX_OK) return err;
// At most one EXIF metadata.
err = ValidateChunk(mux, IDX_EXIF, EXIF_FLAG, flags, 1, &num_exif);
if (err != WEBP_MUX_OK) return err;
// At most one XMP metadata.
err = ValidateChunk(mux, IDX_XMP, XMP_FLAG, flags, 1, &num_xmp);
if (err != WEBP_MUX_OK) return err;
// Animation: ANIMATION_FLAG, ANIM chunk and ANMF chunk(s) are consistent.
// At most one ANIM chunk.
err = ValidateChunk(mux, IDX_ANIM, NO_FLAG, flags, 1, &num_anim);
if (err != WEBP_MUX_OK) return err;
err = ValidateChunk(mux, IDX_ANMF, NO_FLAG, flags, -1, &num_frames);
if (err != WEBP_MUX_OK) return err;
{
const int has_animation = !!(flags & ANIMATION_FLAG);
if (has_animation && (num_anim == 0 || num_frames == 0)) {
return WEBP_MUX_INVALID_ARGUMENT;
}
if (!has_animation && (num_anim == 1 || num_frames > 0)) {
return WEBP_MUX_INVALID_ARGUMENT;
}
if (!has_animation) {
const WebPMuxImage* images = mux->images_;
// There can be only one image.
if (images == NULL || images->next_ != NULL) {
return WEBP_MUX_INVALID_ARGUMENT;
}
// Size must match.
if (mux->canvas_width_ > 0) {
if (images->width_ != mux->canvas_width_ ||
images->height_ != mux->canvas_height_) {
return WEBP_MUX_INVALID_ARGUMENT;
}
}
}
}
// Verify either VP8X chunk is present OR there is only one elem in
// mux->images_.
err = ValidateChunk(mux, IDX_VP8X, NO_FLAG, flags, 1, &num_vp8x);
if (err != WEBP_MUX_OK) return err;
err = ValidateChunk(mux, IDX_VP8, NO_FLAG, flags, -1, &num_images);
if (err != WEBP_MUX_OK) return err;
if (num_vp8x == 0 && num_images != 1) return WEBP_MUX_INVALID_ARGUMENT;
// ALPHA_FLAG & alpha chunk(s) are consistent.
// Note: ALPHA_FLAG can be set when there is actually no Alpha data present.
if (MuxHasAlpha(mux->images_)) {
if (num_vp8x > 0) {
// VP8X chunk is present, so it should contain ALPHA_FLAG.
if (!(flags & ALPHA_FLAG)) return WEBP_MUX_INVALID_ARGUMENT;
} else {
// VP8X chunk is not present, so ALPH chunks should NOT be present either.
err = WebPMuxNumChunks(mux, WEBP_CHUNK_ALPHA, &num_alpha);
if (err != WEBP_MUX_OK) return err;
if (num_alpha > 0) return WEBP_MUX_INVALID_ARGUMENT;
}
}
return WEBP_MUX_OK;
}