Mux: support parsing unknown chunks within a frame/fragment.

Change-Id: I9b4dc36c5ccc4b46f60cd64c1ee21008e20c8b95
This commit is contained in:
Urvang Joshi 2013-07-22 16:40:24 -07:00
parent 8ba1bf61a0
commit 52508a1fe4
4 changed files with 36 additions and 22 deletions

View File

@ -39,12 +39,6 @@ WebPMux* WebPNewInternal(int version) {
}
}
static void DeleteAllChunks(WebPChunk** const chunk_list) {
while (*chunk_list) {
*chunk_list = ChunkDelete(*chunk_list);
}
}
// Delete all images in 'wpi_list'.
static void DeleteAllImages(WebPMuxImage** const wpi_list) {
while (*wpi_list != NULL) {
@ -55,12 +49,12 @@ static void DeleteAllImages(WebPMuxImage** const wpi_list) {
static void MuxRelease(WebPMux* const mux) {
if (mux == NULL) return;
DeleteAllImages(&mux->images_);
DeleteAllChunks(&mux->vp8x_);
DeleteAllChunks(&mux->iccp_);
DeleteAllChunks(&mux->anim_);
DeleteAllChunks(&mux->exif_);
DeleteAllChunks(&mux->xmp_);
DeleteAllChunks(&mux->unknown_);
ChunkListDelete(&mux->vp8x_);
ChunkListDelete(&mux->iccp_);
ChunkListDelete(&mux->anim_);
ChunkListDelete(&mux->exif_);
ChunkListDelete(&mux->xmp_);
ChunkListDelete(&mux->unknown_);
}
void WebPMuxDelete(WebPMux* mux) {
@ -583,16 +577,6 @@ static WebPMuxError MuxCleanup(WebPMux* const mux) {
return WEBP_MUX_OK;
}
// Total size of a list of chunks.
static size_t ChunkListDiskSize(const WebPChunk* chunk_list) {
size_t size = 0;
while (chunk_list != NULL) {
size += ChunkDiskSize(chunk_list);
chunk_list = chunk_list->next_;
}
return size;
}
// Total size of a list of images.
static size_t ImageListDiskSize(const WebPMuxImage* wpi_list) {
size_t size = 0;

View File

@ -48,6 +48,7 @@ struct WebPMuxImage {
WebPChunk* header_; // Corresponds to WEBP_CHUNK_ANMF/WEBP_CHUNK_FRGM.
WebPChunk* alpha_; // Corresponds to WEBP_CHUNK_ALPHA.
WebPChunk* img_; // Corresponds to WEBP_CHUNK_IMAGE.
WebPChunk* unknown_; // Corresponds to WEBP_CHUNK_UNKNOWN.
int width_;
int height_;
int has_alpha_; // Through ALPH chunk or as part of VP8L.
@ -136,6 +137,9 @@ WebPChunk* ChunkRelease(WebPChunk* const chunk);
// Deletes given chunk & returns chunk->next_.
WebPChunk* ChunkDelete(WebPChunk* const chunk);
// Deletes all chunks in the given chunk list.
void ChunkListDelete(WebPChunk** const chunk_list);
// Returns size of the chunk including chunk header and padding byte (if any).
static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {
return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U);
@ -148,6 +152,9 @@ static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) {
return SizeWithPadding(data_size);
}
// Total size of a list of chunks.
size_t ChunkListDiskSize(const WebPChunk* chunk_list);
// Write out the given list of chunks into 'dst'.
uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);

View File

@ -187,6 +187,12 @@ WebPChunk* ChunkDelete(WebPChunk* const chunk) {
return next;
}
void ChunkListDelete(WebPChunk** const chunk_list) {
while (*chunk_list != NULL) {
*chunk_list = ChunkDelete(*chunk_list);
}
}
//------------------------------------------------------------------------------
// Chunk serialization methods.
@ -211,6 +217,15 @@ uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst) {
return dst;
}
size_t ChunkListDiskSize(const WebPChunk* chunk_list) {
size_t size = 0;
while (chunk_list != NULL) {
size += ChunkDiskSize(chunk_list);
chunk_list = chunk_list->next_;
}
return size;
}
//------------------------------------------------------------------------------
// Life of a MuxImage object.
@ -225,6 +240,7 @@ WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) {
ChunkDelete(wpi->header_);
ChunkDelete(wpi->alpha_);
ChunkDelete(wpi->img_);
ChunkListDelete(&wpi->unknown_);
next = wpi->next_;
MuxImageInit(wpi);
@ -356,6 +372,7 @@ size_t MuxImageDiskSize(const WebPMuxImage* const wpi) {
if (wpi->header_ != NULL) size += ChunkDiskSize(wpi->header_);
if (wpi->alpha_ != NULL) size += ChunkDiskSize(wpi->alpha_);
if (wpi->img_ != NULL) size += ChunkDiskSize(wpi->img_);
if (wpi->unknown_ != NULL) size += ChunkListDiskSize(wpi->unknown_);
return size;
}
@ -387,6 +404,7 @@ uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst) {
}
if (wpi->alpha_ != NULL) dst = ChunkEmit(wpi->alpha_, dst);
if (wpi->img_ != NULL) dst = ChunkEmit(wpi->img_, dst);
if (wpi->unknown_ != NULL) dst = ChunkListEmit(wpi->unknown_, dst);
return dst;
}

View File

@ -147,6 +147,11 @@ static int MuxImageParse(const WebPChunk* const chunk, int copy_data,
if (!MuxImageFinalize(wpi)) goto Fail;
wpi->is_partial_ = 0; // wpi is completely filled.
break;
case WEBP_CHUNK_UNKNOWN:
if (wpi->is_partial_) goto Fail; // Encountered an unknown chunk
// before some image chunks.
if (ChunkSetNth(&subchunk, &wpi->unknown_, 0) != WEBP_MUX_OK) goto Fail;
break;
default:
goto Fail;
break;