factorize WebPMuxValidate

move count extraction, count and feature flag validation to
ValidateChunk.

Change-Id: I4bd81bbc8a5a48e1263d11992ab3f285c45417b8
This commit is contained in:
James Zern 2012-02-15 11:54:10 -08:00
parent 14f6b9f606
commit 4be52f4a65

View File

@ -453,6 +453,27 @@ static int IsNotCompatible(int feature, int num_items) {
return (feature != 0) != (num_items > 0);
}
#define NO_FLAG 0
// Test basic constraints:
// retrieval, maximum number of chunks by id (use -1 to skip)
// and feature incompatibility (use NO_FLAG to skip).
// On success returns WEBP_MUX_OK and stores the chunk count in *num.
static WebPMuxError ValidateChunk(const WebPMux* const mux, TAG_ID id,
FeatureFlags feature, FeatureFlags vp8x_flags,
int max, int* num) {
const WebPMuxError err =
WebPMuxNumNamedElements(mux, kChunks[id].chunkName, num);
assert(id == kChunks[id].chunkId);
if (err != WEBP_MUX_OK) return err;
if (max > -1 && *num > max) return WEBP_MUX_INVALID_ARGUMENT;
if (feature != NO_FLAG && IsNotCompatible(vp8x_flags & feature, *num)) {
return WEBP_MUX_INVALID_ARGUMENT;
}
return WEBP_MUX_OK;
}
WebPMuxError WebPMuxValidate(const WebPMux* const mux) {
int num_iccp;
int num_meta;
@ -480,68 +501,45 @@ WebPMuxError WebPMuxValidate(const WebPMux* const mux) {
if (err != WEBP_MUX_OK) return err;
// At most one color profile chunk.
err = WebPMuxNumNamedElements(mux, kChunks[ICCP_ID].chunkName, &num_iccp);
err = ValidateChunk(mux, ICCP_ID, ICCP_FLAG, flags, 1, &num_iccp);
if (err != WEBP_MUX_OK) return err;
if (num_iccp > 1) return WEBP_MUX_INVALID_ARGUMENT;
// ICCP_FLAG and color profile chunk is consistent.
if (IsNotCompatible(flags & ICCP_FLAG, num_iccp)) {
return WEBP_MUX_INVALID_ARGUMENT;
}
// At most one XMP metadata.
err = WebPMuxNumNamedElements(mux, kChunks[META_ID].chunkName, &num_meta);
err = ValidateChunk(mux, META_ID, META_FLAG, flags, 1, &num_meta);
if (err != WEBP_MUX_OK) return err;
if (num_meta > 1) return WEBP_MUX_INVALID_ARGUMENT;
// META_FLAG and XMP metadata chunk is consistent.
if (IsNotCompatible(flags & META_FLAG, num_meta)) {
return WEBP_MUX_INVALID_ARGUMENT;
}
// At most one loop chunk.
err = WebPMuxNumNamedElements(mux, kChunks[LOOP_ID].chunkName,
&num_loop_chunks);
if (err != WEBP_MUX_OK) return err;
if (num_loop_chunks > 1) return WEBP_MUX_INVALID_ARGUMENT;
// Animation: ANIMATION_FLAG, loop chunk and frame chunk(s) are consistent.
err = WebPMuxNumNamedElements(mux, kChunks[FRAME_ID].chunkName, &num_frames);
// At most one loop chunk.
err = ValidateChunk(mux, LOOP_ID, NO_FLAG, flags, 1, &num_loop_chunks);
if (err != WEBP_MUX_OK) return err;
if ((flags & ANIMATION_FLAG) &&
(num_loop_chunks == 0 || num_frames == 0)) {
return WEBP_MUX_INVALID_ARGUMENT;
} else if (!(flags & ANIMATION_FLAG) &&
(num_loop_chunks == 1 || num_frames > 0)) {
return WEBP_MUX_INVALID_ARGUMENT;
err = ValidateChunk(mux, FRAME_ID, NO_FLAG, flags, -1, &num_frames);
if (err != WEBP_MUX_OK) return err;
{
const int has_animation = !!(flags & ANIMATION_FLAG);
if (has_animation && (num_loop_chunks == 0 || num_frames == 0)) {
return WEBP_MUX_INVALID_ARGUMENT;
}
if (!has_animation && (num_loop_chunks == 1 || num_frames > 0)) {
return WEBP_MUX_INVALID_ARGUMENT;
}
}
// Tiling: TILE_FLAG and tile chunk(s) are consistent.
err = WebPMuxNumNamedElements(mux, kChunks[TILE_ID].chunkName, &num_tiles);
err = ValidateChunk(mux, TILE_ID, TILE_FLAG, flags, -1, &num_tiles);
if (err != WEBP_MUX_OK) return err;
if (IsNotCompatible(flags & TILE_FLAG, num_tiles)) {
return WEBP_MUX_INVALID_ARGUMENT;
}
// Verify either VP8X chunk is present OR there is only one elem in
// mux->images_.
err = WebPMuxNumNamedElements(mux, kChunks[VP8X_ID].chunkName, &num_vp8x);
err = ValidateChunk(mux, VP8X_ID, NO_FLAG, flags, 1, &num_vp8x);
if (err != WEBP_MUX_OK) return err;
err = WebPMuxNumNamedElements(mux, kChunks[IMAGE_ID].chunkName, &num_images);
err = ValidateChunk(mux, IMAGE_ID, NO_FLAG, flags, -1, &num_images);
if (err != WEBP_MUX_OK) return err;
if (num_vp8x > 1) {
return WEBP_MUX_INVALID_ARGUMENT;
} else if (num_vp8x == 0 && num_images != 1) {
return WEBP_MUX_INVALID_ARGUMENT;
}
if (num_vp8x == 0 && num_images != 1) return WEBP_MUX_INVALID_ARGUMENT;
// ALPHA_FLAG & alpha chunk(s) are consistent.
err = WebPMuxNumNamedElements(mux, kChunks[ALPHA_ID].chunkName, &num_alpha);
err = ValidateChunk(mux, ALPHA_ID, ALPHA_FLAG, flags, -1, &num_alpha);
if (err != WEBP_MUX_OK) return err;
if (IsNotCompatible(flags & ALPHA_FLAG, num_alpha)) {
return WEBP_MUX_INVALID_ARGUMENT;
}
// num_images & num_alpha_chunks are consistent.
if (num_alpha > 0 && num_alpha != num_images) {
@ -553,6 +551,8 @@ WebPMuxError WebPMuxValidate(const WebPMux* const mux) {
return WEBP_MUX_OK;
}
#undef NO_FLAG
//------------------------------------------------------------------------------
#if defined(__cplusplus) || defined(c_plusplus)