mirror of
https://github.com/webmproject/libwebp.git
synced 2025-04-11 11:26:47 +02:00
Merge changes I48968468,I181bc736
* changes: demux: split chunk parsing from ParseVP8X demux: add a tail pointer for chunks
This commit is contained in:
commit
bcb3955c41
@ -75,6 +75,7 @@ struct WebPDemuxer {
|
|||||||
Frame* frames_;
|
Frame* frames_;
|
||||||
Frame** frames_tail_;
|
Frame** frames_tail_;
|
||||||
Chunk* chunks_; // non-image chunks
|
Chunk* chunks_; // non-image chunks
|
||||||
|
Chunk** chunks_tail_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -179,10 +180,9 @@ static WEBP_INLINE uint32_t ReadLE32(MemBuffer* const mem) {
|
|||||||
// Secondary chunk parsing
|
// Secondary chunk parsing
|
||||||
|
|
||||||
static void AddChunk(WebPDemuxer* const dmux, Chunk* const chunk) {
|
static void AddChunk(WebPDemuxer* const dmux, Chunk* const chunk) {
|
||||||
Chunk** c = &dmux->chunks_;
|
*dmux->chunks_tail_ = chunk;
|
||||||
while (*c != NULL) c = &(*c)->next_;
|
|
||||||
*c = chunk;
|
|
||||||
chunk->next_ = NULL;
|
chunk->next_ = NULL;
|
||||||
|
dmux->chunks_tail_ = &chunk->next_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a frame to the end of the list, ensuring the last frame is complete.
|
// Add a frame to the end of the list, ensuring the last frame is complete.
|
||||||
@ -466,36 +466,12 @@ static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
|
static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) {
|
||||||
|
const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG);
|
||||||
MemBuffer* const mem = &dmux->mem_;
|
MemBuffer* const mem = &dmux->mem_;
|
||||||
int anim_chunks = 0;
|
int anim_chunks = 0;
|
||||||
uint32_t vp8x_size;
|
|
||||||
ParseStatus status = PARSE_OK;
|
ParseStatus status = PARSE_OK;
|
||||||
|
|
||||||
if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
|
|
||||||
|
|
||||||
dmux->is_ext_format_ = 1;
|
|
||||||
Skip(mem, TAG_SIZE); // VP8X
|
|
||||||
vp8x_size = ReadLE32(mem);
|
|
||||||
if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
|
|
||||||
if (vp8x_size < VP8X_CHUNK_SIZE) return PARSE_ERROR;
|
|
||||||
vp8x_size += vp8x_size & 1;
|
|
||||||
if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR;
|
|
||||||
if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA;
|
|
||||||
|
|
||||||
dmux->feature_flags_ = ReadByte(mem);
|
|
||||||
Skip(mem, 3); // Reserved.
|
|
||||||
dmux->canvas_width_ = 1 + ReadLE24s(mem);
|
|
||||||
dmux->canvas_height_ = 1 + ReadLE24s(mem);
|
|
||||||
if (dmux->canvas_width_ * (uint64_t)dmux->canvas_height_ >= MAX_IMAGE_AREA) {
|
|
||||||
return PARSE_ERROR; // image final dimension is too large
|
|
||||||
}
|
|
||||||
Skip(mem, vp8x_size - VP8X_CHUNK_SIZE); // skip any trailing data.
|
|
||||||
dmux->state_ = WEBP_DEMUX_PARSED_HEADER;
|
|
||||||
|
|
||||||
if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR;
|
|
||||||
if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int store_chunk = 1;
|
int store_chunk = 1;
|
||||||
const size_t chunk_start_offset = mem->start_;
|
const size_t chunk_start_offset = mem->start_;
|
||||||
@ -513,7 +489,6 @@ static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
|
|||||||
case MKFOURCC('A', 'L', 'P', 'H'):
|
case MKFOURCC('A', 'L', 'P', 'H'):
|
||||||
case MKFOURCC('V', 'P', '8', ' '):
|
case MKFOURCC('V', 'P', '8', ' '):
|
||||||
case MKFOURCC('V', 'P', '8', 'L'): {
|
case MKFOURCC('V', 'P', '8', 'L'): {
|
||||||
const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG);
|
|
||||||
// check that this isn't an animation (all frames should be in an ANMF).
|
// check that this isn't an animation (all frames should be in an ANMF).
|
||||||
if (anim_chunks > 0 || is_animation) return PARSE_ERROR;
|
if (anim_chunks > 0 || is_animation) return PARSE_ERROR;
|
||||||
|
|
||||||
@ -552,14 +527,14 @@ static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
|
|||||||
store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG);
|
store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG);
|
||||||
goto Skip;
|
goto Skip;
|
||||||
}
|
}
|
||||||
case MKFOURCC('X', 'M', 'P', ' '): {
|
|
||||||
store_chunk = !!(dmux->feature_flags_ & XMP_FLAG);
|
|
||||||
goto Skip;
|
|
||||||
}
|
|
||||||
case MKFOURCC('E', 'X', 'I', 'F'): {
|
case MKFOURCC('E', 'X', 'I', 'F'): {
|
||||||
store_chunk = !!(dmux->feature_flags_ & EXIF_FLAG);
|
store_chunk = !!(dmux->feature_flags_ & EXIF_FLAG);
|
||||||
goto Skip;
|
goto Skip;
|
||||||
}
|
}
|
||||||
|
case MKFOURCC('X', 'M', 'P', ' '): {
|
||||||
|
store_chunk = !!(dmux->feature_flags_ & XMP_FLAG);
|
||||||
|
goto Skip;
|
||||||
|
}
|
||||||
Skip:
|
Skip:
|
||||||
default: {
|
default: {
|
||||||
if (chunk_size_padded <= MemDataSize(mem)) {
|
if (chunk_size_padded <= MemDataSize(mem)) {
|
||||||
@ -588,6 +563,37 @@ static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
|
||||||
|
MemBuffer* const mem = &dmux->mem_;
|
||||||
|
uint32_t vp8x_size;
|
||||||
|
|
||||||
|
if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
|
||||||
|
|
||||||
|
dmux->is_ext_format_ = 1;
|
||||||
|
Skip(mem, TAG_SIZE); // VP8X
|
||||||
|
vp8x_size = ReadLE32(mem);
|
||||||
|
if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
|
||||||
|
if (vp8x_size < VP8X_CHUNK_SIZE) return PARSE_ERROR;
|
||||||
|
vp8x_size += vp8x_size & 1;
|
||||||
|
if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR;
|
||||||
|
if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA;
|
||||||
|
|
||||||
|
dmux->feature_flags_ = ReadByte(mem);
|
||||||
|
Skip(mem, 3); // Reserved.
|
||||||
|
dmux->canvas_width_ = 1 + ReadLE24s(mem);
|
||||||
|
dmux->canvas_height_ = 1 + ReadLE24s(mem);
|
||||||
|
if (dmux->canvas_width_ * (uint64_t)dmux->canvas_height_ >= MAX_IMAGE_AREA) {
|
||||||
|
return PARSE_ERROR; // image final dimension is too large
|
||||||
|
}
|
||||||
|
Skip(mem, vp8x_size - VP8X_CHUNK_SIZE); // skip any trailing data.
|
||||||
|
dmux->state_ = WEBP_DEMUX_PARSED_HEADER;
|
||||||
|
|
||||||
|
if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR;
|
||||||
|
if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
|
||||||
|
|
||||||
|
return ParseVP8XChunks(dmux);
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Format validation
|
// Format validation
|
||||||
|
|
||||||
@ -697,6 +703,7 @@ static void InitDemux(WebPDemuxer* const dmux, const MemBuffer* const mem) {
|
|||||||
dmux->canvas_width_ = -1;
|
dmux->canvas_width_ = -1;
|
||||||
dmux->canvas_height_ = -1;
|
dmux->canvas_height_ = -1;
|
||||||
dmux->frames_tail_ = &dmux->frames_;
|
dmux->frames_tail_ = &dmux->frames_;
|
||||||
|
dmux->chunks_tail_ = &dmux->chunks_;
|
||||||
dmux->mem_ = *mem;
|
dmux->mem_ = *mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user