Mux: support parsing unknown chunks within a frame/fragment.
Change-Id: I9b4dc36c5ccc4b46f60cd64c1ee21008e20c8b95
This commit is contained in:
parent
8ba1bf61a0
commit
52508a1fe4
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user