mirror of
https://github.com/webmproject/libwebp.git
synced 2025-02-13 15:32:53 +01:00
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'.
|
// Delete all images in 'wpi_list'.
|
||||||
static void DeleteAllImages(WebPMuxImage** const wpi_list) {
|
static void DeleteAllImages(WebPMuxImage** const wpi_list) {
|
||||||
while (*wpi_list != NULL) {
|
while (*wpi_list != NULL) {
|
||||||
@ -55,12 +49,12 @@ static void DeleteAllImages(WebPMuxImage** const wpi_list) {
|
|||||||
static void MuxRelease(WebPMux* const mux) {
|
static void MuxRelease(WebPMux* const mux) {
|
||||||
if (mux == NULL) return;
|
if (mux == NULL) return;
|
||||||
DeleteAllImages(&mux->images_);
|
DeleteAllImages(&mux->images_);
|
||||||
DeleteAllChunks(&mux->vp8x_);
|
ChunkListDelete(&mux->vp8x_);
|
||||||
DeleteAllChunks(&mux->iccp_);
|
ChunkListDelete(&mux->iccp_);
|
||||||
DeleteAllChunks(&mux->anim_);
|
ChunkListDelete(&mux->anim_);
|
||||||
DeleteAllChunks(&mux->exif_);
|
ChunkListDelete(&mux->exif_);
|
||||||
DeleteAllChunks(&mux->xmp_);
|
ChunkListDelete(&mux->xmp_);
|
||||||
DeleteAllChunks(&mux->unknown_);
|
ChunkListDelete(&mux->unknown_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebPMuxDelete(WebPMux* mux) {
|
void WebPMuxDelete(WebPMux* mux) {
|
||||||
@ -583,16 +577,6 @@ static WebPMuxError MuxCleanup(WebPMux* const mux) {
|
|||||||
return WEBP_MUX_OK;
|
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.
|
// Total size of a list of images.
|
||||||
static size_t ImageListDiskSize(const WebPMuxImage* wpi_list) {
|
static size_t ImageListDiskSize(const WebPMuxImage* wpi_list) {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
@ -48,6 +48,7 @@ struct WebPMuxImage {
|
|||||||
WebPChunk* header_; // Corresponds to WEBP_CHUNK_ANMF/WEBP_CHUNK_FRGM.
|
WebPChunk* header_; // Corresponds to WEBP_CHUNK_ANMF/WEBP_CHUNK_FRGM.
|
||||||
WebPChunk* alpha_; // Corresponds to WEBP_CHUNK_ALPHA.
|
WebPChunk* alpha_; // Corresponds to WEBP_CHUNK_ALPHA.
|
||||||
WebPChunk* img_; // Corresponds to WEBP_CHUNK_IMAGE.
|
WebPChunk* img_; // Corresponds to WEBP_CHUNK_IMAGE.
|
||||||
|
WebPChunk* unknown_; // Corresponds to WEBP_CHUNK_UNKNOWN.
|
||||||
int width_;
|
int width_;
|
||||||
int height_;
|
int height_;
|
||||||
int has_alpha_; // Through ALPH chunk or as part of VP8L.
|
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_.
|
// Deletes given chunk & returns chunk->next_.
|
||||||
WebPChunk* ChunkDelete(WebPChunk* const chunk);
|
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).
|
// Returns size of the chunk including chunk header and padding byte (if any).
|
||||||
static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {
|
static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {
|
||||||
return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U);
|
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);
|
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'.
|
// Write out the given list of chunks into 'dst'.
|
||||||
uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);
|
uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);
|
||||||
|
|
||||||
|
@ -187,6 +187,12 @@ WebPChunk* ChunkDelete(WebPChunk* const chunk) {
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChunkListDelete(WebPChunk** const chunk_list) {
|
||||||
|
while (*chunk_list != NULL) {
|
||||||
|
*chunk_list = ChunkDelete(*chunk_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Chunk serialization methods.
|
// Chunk serialization methods.
|
||||||
|
|
||||||
@ -211,6 +217,15 @@ uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst) {
|
|||||||
return 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.
|
// Life of a MuxImage object.
|
||||||
|
|
||||||
@ -225,6 +240,7 @@ WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) {
|
|||||||
ChunkDelete(wpi->header_);
|
ChunkDelete(wpi->header_);
|
||||||
ChunkDelete(wpi->alpha_);
|
ChunkDelete(wpi->alpha_);
|
||||||
ChunkDelete(wpi->img_);
|
ChunkDelete(wpi->img_);
|
||||||
|
ChunkListDelete(&wpi->unknown_);
|
||||||
|
|
||||||
next = wpi->next_;
|
next = wpi->next_;
|
||||||
MuxImageInit(wpi);
|
MuxImageInit(wpi);
|
||||||
@ -356,6 +372,7 @@ size_t MuxImageDiskSize(const WebPMuxImage* const wpi) {
|
|||||||
if (wpi->header_ != NULL) size += ChunkDiskSize(wpi->header_);
|
if (wpi->header_ != NULL) size += ChunkDiskSize(wpi->header_);
|
||||||
if (wpi->alpha_ != NULL) size += ChunkDiskSize(wpi->alpha_);
|
if (wpi->alpha_ != NULL) size += ChunkDiskSize(wpi->alpha_);
|
||||||
if (wpi->img_ != NULL) size += ChunkDiskSize(wpi->img_);
|
if (wpi->img_ != NULL) size += ChunkDiskSize(wpi->img_);
|
||||||
|
if (wpi->unknown_ != NULL) size += ChunkListDiskSize(wpi->unknown_);
|
||||||
return size;
|
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->alpha_ != NULL) dst = ChunkEmit(wpi->alpha_, dst);
|
||||||
if (wpi->img_ != NULL) dst = ChunkEmit(wpi->img_, dst);
|
if (wpi->img_ != NULL) dst = ChunkEmit(wpi->img_, dst);
|
||||||
|
if (wpi->unknown_ != NULL) dst = ChunkListEmit(wpi->unknown_, dst);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +147,11 @@ static int MuxImageParse(const WebPChunk* const chunk, int copy_data,
|
|||||||
if (!MuxImageFinalize(wpi)) goto Fail;
|
if (!MuxImageFinalize(wpi)) goto Fail;
|
||||||
wpi->is_partial_ = 0; // wpi is completely filled.
|
wpi->is_partial_ = 0; // wpi is completely filled.
|
||||||
break;
|
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:
|
default:
|
||||||
goto Fail;
|
goto Fail;
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user