mirror of
https://github.com/webmproject/libwebp.git
synced 2025-08-29 15:22:12 +02:00
Use 'frgm' instead of 'tile' in webpmux parameters
- Also, use the term 'fragments' instead of 'tiling' in code - This makes code consistent with the spec. Change-Id: Ibeccffc35db23bbedb88cc5e18e29e51621931f8
This commit is contained in:
108
src/mux/demux.c
108
src/mux/demux.c
@@ -39,8 +39,8 @@ typedef struct Frame {
|
||||
int x_offset_, y_offset_;
|
||||
int width_, height_;
|
||||
int duration_;
|
||||
int is_tile_; // this is an image fragment from a tile.
|
||||
int frame_num_; // the referent frame number for use in assembling tiles.
|
||||
int is_fragment_; // this is a frame fragment (and not a full frame).
|
||||
int frame_num_; // the referent frame number for use in assembling fragments.
|
||||
int complete_; // img_components_ contains a full image.
|
||||
ChunkData img_components_[2]; // 0=VP8{,L} 1=ALPH
|
||||
struct Frame* next_;
|
||||
@@ -327,35 +327,36 @@ static ParseStatus ParseFrame(
|
||||
}
|
||||
|
||||
// Parse a 'FRGM' chunk and any image bearing chunks that immediately follow.
|
||||
// 'tile_chunk_size' is the previously validated, padded chunk size.
|
||||
static ParseStatus ParseTile(WebPDemuxer* const dmux,
|
||||
uint32_t tile_chunk_size) {
|
||||
const int has_tiles = !!(dmux->feature_flags_ & TILE_FLAG);
|
||||
// 'fragment_chunk_size' is the previously validated, padded chunk size.
|
||||
static ParseStatus ParseFragment(WebPDemuxer* const dmux,
|
||||
uint32_t fragment_chunk_size) {
|
||||
const int has_fragments = !!(dmux->feature_flags_ & FRAGMENTS_FLAG);
|
||||
const uint32_t padding = (FRGM_CHUNK_SIZE & 1);
|
||||
const uint32_t frgm_payload_size =
|
||||
tile_chunk_size - (FRGM_CHUNK_SIZE + padding);
|
||||
int added_tile = 0;
|
||||
fragment_chunk_size - (FRGM_CHUNK_SIZE + padding);
|
||||
int added_fragment = 0;
|
||||
MemBuffer* const mem = &dmux->mem_;
|
||||
Frame* frame;
|
||||
ParseStatus status =
|
||||
NewFrame(mem, FRGM_CHUNK_SIZE, tile_chunk_size, &frame);
|
||||
NewFrame(mem, FRGM_CHUNK_SIZE, fragment_chunk_size, &frame);
|
||||
if (status != PARSE_OK) return status;
|
||||
|
||||
frame->is_tile_ = 1;
|
||||
frame->is_fragment_ = 1;
|
||||
frame->x_offset_ = 2 * GetLE24s(mem);
|
||||
frame->y_offset_ = 2 * GetLE24s(mem);
|
||||
Skip(mem, padding);
|
||||
|
||||
// Store a tile only if the tile flag is set and all data for this tile
|
||||
// is available.
|
||||
// Store a fragment only if the fragments flag is set and all data for this
|
||||
// fragment is available.
|
||||
status = StoreFrame(dmux->num_frames_, frgm_payload_size, mem, frame);
|
||||
if (status != PARSE_ERROR && has_tiles && frame->frame_num_ > 0) {
|
||||
// Note num_frames_ is incremented only when all tiles have been consumed.
|
||||
added_tile = AddFrame(dmux, frame);
|
||||
if (!added_tile) status = PARSE_ERROR;
|
||||
if (status != PARSE_ERROR && has_fragments && frame->frame_num_ > 0) {
|
||||
// Note num_frames_ is incremented only when all fragments have been
|
||||
// consumed.
|
||||
added_fragment = AddFrame(dmux, frame);
|
||||
if (!added_fragment) status = PARSE_ERROR;
|
||||
}
|
||||
|
||||
if (!added_tile) free(frame);
|
||||
if (!added_fragment) free(frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -513,7 +514,7 @@ static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
|
||||
}
|
||||
case MKFOURCC('F', 'R', 'G', 'M'): {
|
||||
if (dmux->num_frames_ == 0) dmux->num_frames_ = 1;
|
||||
status = ParseTile(dmux, chunk_size_padded);
|
||||
status = ParseFragment(dmux, chunk_size_padded);
|
||||
break;
|
||||
}
|
||||
case MKFOURCC('I', 'C', 'C', 'P'): {
|
||||
@@ -571,7 +572,7 @@ static int IsValidSimpleFormat(const WebPDemuxer* const dmux) {
|
||||
}
|
||||
|
||||
static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
|
||||
const int has_tiles = !!(dmux->feature_flags_ & TILE_FLAG);
|
||||
const int has_fragments = !!(dmux->feature_flags_ & FRAGMENTS_FLAG);
|
||||
const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG);
|
||||
const Frame* f;
|
||||
|
||||
@@ -583,15 +584,15 @@ static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
|
||||
|
||||
for (f = dmux->frames_; f != NULL; f = f->next_) {
|
||||
const int cur_frame_set = f->frame_num_;
|
||||
int frame_count = 0, tile_count = 0;
|
||||
int frame_count = 0, fragment_count = 0;
|
||||
|
||||
// Check frame properties and if the image is composed of tiles that each
|
||||
// fragment came from a tile.
|
||||
// Check frame properties and if the image is composed of fragments that
|
||||
// each fragment came from a fragment.
|
||||
for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) {
|
||||
const ChunkData* const image = f->img_components_;
|
||||
const ChunkData* const alpha = f->img_components_ + 1;
|
||||
|
||||
if (!has_tiles && f->is_tile_) return 0;
|
||||
if (!has_fragments && f->is_fragment_) return 0;
|
||||
if (!has_frames && f->frame_num_ > 1) return 0;
|
||||
if (f->x_offset_ < 0 || f->y_offset_ < 0) return 0;
|
||||
if (f->complete_) {
|
||||
@@ -612,11 +613,11 @@ static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
|
||||
if (f->next_ != NULL) return 0;
|
||||
}
|
||||
|
||||
tile_count += f->is_tile_;
|
||||
fragment_count += f->is_fragment_;
|
||||
++frame_count;
|
||||
}
|
||||
if (!has_tiles && frame_count > 1) return 0;
|
||||
if (tile_count > 0 && frame_count != tile_count) return 0;
|
||||
if (!has_fragments && frame_count > 1) return 0;
|
||||
if (fragment_count > 0 && frame_count != fragment_count) return 0;
|
||||
if (f == NULL) break;
|
||||
}
|
||||
return 1;
|
||||
@@ -706,7 +707,8 @@ uint32_t WebPDemuxGetI(const WebPDemuxer* dmux, WebPFormatFeature feature) {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Frame iteration
|
||||
|
||||
// Find the first 'frame_num' frame. There may be multiple in a tiled frame.
|
||||
// Find the first 'frame_num' frame. There may be multiple such frames in a
|
||||
// fragmented frame.
|
||||
static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) {
|
||||
const Frame* f;
|
||||
for (f = dmux->frames_; f != NULL; f = f->next_) {
|
||||
@@ -715,19 +717,19 @@ static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) {
|
||||
return f;
|
||||
}
|
||||
|
||||
// Returns tile 'tile_num' and the total count.
|
||||
static const Frame* GetTile(
|
||||
const Frame* const frame_set, int tile_num, int* const count) {
|
||||
// Returns fragment 'fragment_num' and the total count.
|
||||
static const Frame* GetFragment(
|
||||
const Frame* const frame_set, int fragment_num, int* const count) {
|
||||
const int this_frame = frame_set->frame_num_;
|
||||
const Frame* f = frame_set;
|
||||
const Frame* tile = NULL;
|
||||
const Frame* fragment = NULL;
|
||||
int total;
|
||||
|
||||
for (total = 0; f != NULL && f->frame_num_ == this_frame; f = f->next_) {
|
||||
if (++total == tile_num) tile = f;
|
||||
if (++total == fragment_num) fragment = f;
|
||||
}
|
||||
*count = total;
|
||||
return tile;
|
||||
return fragment;
|
||||
}
|
||||
|
||||
static const uint8_t* GetFramePayload(const uint8_t* const mem_buf,
|
||||
@@ -757,26 +759,28 @@ static const uint8_t* GetFramePayload(const uint8_t* const mem_buf,
|
||||
// Create a whole 'frame' from VP8 (+ alpha) or lossless.
|
||||
static int SynthesizeFrame(const WebPDemuxer* const dmux,
|
||||
const Frame* const first_frame,
|
||||
int tile_num, WebPIterator* const iter) {
|
||||
int fragment_num, WebPIterator* const iter) {
|
||||
const uint8_t* const mem_buf = dmux->mem_.buf_;
|
||||
int num_tiles;
|
||||
int num_fragments;
|
||||
size_t payload_size = 0;
|
||||
const Frame* const tile = GetTile(first_frame, tile_num, &num_tiles);
|
||||
const uint8_t* const payload = GetFramePayload(mem_buf, tile, &payload_size);
|
||||
const Frame* const fragment =
|
||||
GetFragment(first_frame, fragment_num, &num_fragments);
|
||||
const uint8_t* const payload =
|
||||
GetFramePayload(mem_buf, fragment, &payload_size);
|
||||
if (payload == NULL) return 0;
|
||||
|
||||
iter->frame_num = first_frame->frame_num_;
|
||||
iter->num_frames = dmux->num_frames_;
|
||||
iter->tile_num = tile_num;
|
||||
iter->num_tiles = num_tiles;
|
||||
iter->x_offset = tile->x_offset_;
|
||||
iter->y_offset = tile->y_offset_;
|
||||
iter->width = tile->width_;
|
||||
iter->height = tile->height_;
|
||||
iter->duration = tile->duration_;
|
||||
iter->complete = tile->complete_;
|
||||
iter->tile.bytes = payload;
|
||||
iter->tile.size = payload_size;
|
||||
iter->frame_num = first_frame->frame_num_;
|
||||
iter->num_frames = dmux->num_frames_;
|
||||
iter->fragment_num = fragment_num;
|
||||
iter->num_fragments = num_fragments;
|
||||
iter->x_offset = fragment->x_offset_;
|
||||
iter->y_offset = fragment->y_offset_;
|
||||
iter->width = fragment->width_;
|
||||
iter->height = fragment->height_;
|
||||
iter->duration = fragment->duration_;
|
||||
iter->complete = fragment->complete_;
|
||||
iter->fragment.bytes = payload;
|
||||
iter->fragment.size = payload_size;
|
||||
// TODO(jzern): adjust offsets for 'FRGM's embedded in 'ANMF's
|
||||
return 1;
|
||||
}
|
||||
@@ -811,13 +815,13 @@ int WebPDemuxPrevFrame(WebPIterator* iter) {
|
||||
return SetFrame(iter->frame_num - 1, iter);
|
||||
}
|
||||
|
||||
int WebPDemuxSelectTile(WebPIterator* iter, int tile) {
|
||||
if (iter != NULL && iter->private_ != NULL && tile > 0) {
|
||||
int WebPDemuxSelectFragment(WebPIterator* iter, int fragment_num) {
|
||||
if (iter != NULL && iter->private_ != NULL && fragment_num > 0) {
|
||||
const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
|
||||
const Frame* const frame = GetFrame(dmux, iter->frame_num);
|
||||
if (frame == NULL) return 0;
|
||||
|
||||
return SynthesizeFrame(dmux, frame, tile, iter);
|
||||
return SynthesizeFrame(dmux, frame, fragment_num, iter);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -109,15 +109,15 @@ static WebPMuxError MuxAddChunk(WebPMux* const mux, uint32_t nth, uint32_t tag,
|
||||
}
|
||||
|
||||
// Create data for frame/tile given image data, offsets and duration.
|
||||
static WebPMuxError CreateFrameTileData(const WebPData* const image,
|
||||
int x_offset, int y_offset,
|
||||
int duration, int is_lossless,
|
||||
int is_frame,
|
||||
WebPData* const frame_tile) {
|
||||
static WebPMuxError CreateFrameFragmentData(const WebPData* const image,
|
||||
int x_offset, int y_offset,
|
||||
int duration, int is_lossless,
|
||||
int is_frame,
|
||||
WebPData* const frame_frgm) {
|
||||
int width;
|
||||
int height;
|
||||
uint8_t* frame_tile_bytes;
|
||||
const size_t frame_tile_size = kChunks[is_frame ? IDX_ANMF : IDX_FRGM].size;
|
||||
uint8_t* frame_frgm_bytes;
|
||||
const size_t frame_frgm_size = kChunks[is_frame ? IDX_ANMF : IDX_FRGM].size;
|
||||
|
||||
const int ok = is_lossless ?
|
||||
VP8LGetInfo(image->bytes, image->size, &width, &height, NULL) :
|
||||
@@ -127,20 +127,20 @@ static WebPMuxError CreateFrameTileData(const WebPData* const image,
|
||||
assert(width > 0 && height > 0 && duration > 0);
|
||||
// Note: assertion on upper bounds is done in PutLE24().
|
||||
|
||||
frame_tile_bytes = (uint8_t*)malloc(frame_tile_size);
|
||||
if (frame_tile_bytes == NULL) return WEBP_MUX_MEMORY_ERROR;
|
||||
frame_frgm_bytes = (uint8_t*)malloc(frame_frgm_size);
|
||||
if (frame_frgm_bytes == NULL) return WEBP_MUX_MEMORY_ERROR;
|
||||
|
||||
PutLE24(frame_tile_bytes + 0, x_offset / 2);
|
||||
PutLE24(frame_tile_bytes + 3, y_offset / 2);
|
||||
PutLE24(frame_frgm_bytes + 0, x_offset / 2);
|
||||
PutLE24(frame_frgm_bytes + 3, y_offset / 2);
|
||||
|
||||
if (is_frame) {
|
||||
PutLE24(frame_tile_bytes + 6, width - 1);
|
||||
PutLE24(frame_tile_bytes + 9, height - 1);
|
||||
PutLE24(frame_tile_bytes + 12, duration - 1);
|
||||
PutLE24(frame_frgm_bytes + 6, width - 1);
|
||||
PutLE24(frame_frgm_bytes + 9, height - 1);
|
||||
PutLE24(frame_frgm_bytes + 12, duration - 1);
|
||||
}
|
||||
|
||||
frame_tile->bytes = frame_tile_bytes;
|
||||
frame_tile->size = frame_tile_size;
|
||||
frame_frgm->bytes = frame_frgm_bytes;
|
||||
frame_frgm->size = frame_frgm_size;
|
||||
return WEBP_MUX_OK;
|
||||
}
|
||||
|
||||
@@ -334,19 +334,19 @@ WebPMuxError WebPMuxPushFrame(WebPMux* mux, const WebPMuxFrameInfo* frame,
|
||||
const int y_offset = frame->y_offset & ~1;
|
||||
const int duration = is_frame ? frame->duration : 1 /* unused */;
|
||||
const uint32_t tag = kChunks[is_frame ? IDX_ANMF : IDX_FRGM].tag;
|
||||
WebPData frame_tile;
|
||||
WebPData frame_frgm;
|
||||
if (x_offset < 0 || x_offset >= MAX_POSITION_OFFSET ||
|
||||
y_offset < 0 || y_offset >= MAX_POSITION_OFFSET ||
|
||||
(duration <= 0 || duration > MAX_DURATION)) {
|
||||
err = WEBP_MUX_INVALID_ARGUMENT;
|
||||
goto Err;
|
||||
}
|
||||
err = CreateFrameTileData(&wpi.img_->data_, x_offset, y_offset, duration,
|
||||
is_lossless, is_frame, &frame_tile);
|
||||
err = CreateFrameFragmentData(&wpi.img_->data_, x_offset, y_offset,
|
||||
duration, is_lossless, is_frame, &frame_frgm);
|
||||
if (err != WEBP_MUX_OK) goto Err;
|
||||
// Add frame/tile chunk (with copy_data = 1).
|
||||
err = AddDataToChunkList(&frame_tile, 1, tag, &wpi.header_);
|
||||
WebPDataClear(&frame_tile); // frame_tile owned by wpi.header_ now.
|
||||
// Add frame/fragment chunk (with copy_data = 1).
|
||||
err = AddDataToChunkList(&frame_frgm, 1, tag, &wpi.header_);
|
||||
WebPDataClear(&frame_frgm); // frame_frgm owned by wpi.header_ now.
|
||||
if (err != WEBP_MUX_OK) goto Err;
|
||||
}
|
||||
|
||||
@@ -394,15 +394,15 @@ WebPMuxError WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Assembly of the WebP RIFF file.
|
||||
|
||||
static WebPMuxError GetFrameTileInfo(const WebPChunk* const frame_tile_chunk,
|
||||
int* const x_offset, int* const y_offset,
|
||||
int* const duration) {
|
||||
const uint32_t tag = frame_tile_chunk->tag_;
|
||||
static WebPMuxError GetFrameFragmentInfo(
|
||||
const WebPChunk* const frame_frgm_chunk,
|
||||
int* const x_offset, int* const y_offset, int* const duration) {
|
||||
const uint32_t tag = frame_frgm_chunk->tag_;
|
||||
const int is_frame = (tag == kChunks[IDX_ANMF].tag);
|
||||
const WebPData* const data = &frame_tile_chunk->data_;
|
||||
const WebPData* const data = &frame_frgm_chunk->data_;
|
||||
const size_t expected_data_size =
|
||||
is_frame ? ANMF_CHUNK_SIZE : FRGM_CHUNK_SIZE;
|
||||
assert(frame_tile_chunk != NULL);
|
||||
assert(frame_frgm_chunk != NULL);
|
||||
assert(tag == kChunks[IDX_ANMF].tag || tag == kChunks[IDX_FRGM].tag);
|
||||
if (data->size != expected_data_size) return WEBP_MUX_INVALID_ARGUMENT;
|
||||
|
||||
@@ -437,11 +437,11 @@ static WebPMuxError GetImageInfo(const WebPMuxImage* const wpi,
|
||||
int* const duration,
|
||||
int* const width, int* const height) {
|
||||
const WebPChunk* const image_chunk = wpi->img_;
|
||||
const WebPChunk* const frame_tile_chunk = wpi->header_;
|
||||
const WebPChunk* const frame_frgm_chunk = wpi->header_;
|
||||
|
||||
// Get offsets and duration from ANMF/FRGM chunk.
|
||||
const WebPMuxError err =
|
||||
GetFrameTileInfo(frame_tile_chunk, x_offset, y_offset, duration);
|
||||
GetFrameFragmentInfo(frame_frgm_chunk, x_offset, y_offset, duration);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
|
||||
// Get width and height from VP8/VP8L chunk.
|
||||
@@ -463,7 +463,7 @@ static WebPMuxError GetImageCanvasWidthHeight(
|
||||
int max_x = 0;
|
||||
int max_y = 0;
|
||||
int64_t image_area = 0;
|
||||
// Aggregate the bounding box for animation frames & tiled images.
|
||||
// Aggregate the bounding box for animation frames & fragmented images.
|
||||
for (; wpi != NULL; wpi = wpi->next_) {
|
||||
int x_offset, y_offset, duration, w, h;
|
||||
const WebPMuxError err = GetImageInfo(wpi, &x_offset, &y_offset,
|
||||
@@ -480,11 +480,11 @@ static WebPMuxError GetImageCanvasWidthHeight(
|
||||
}
|
||||
*width = max_x;
|
||||
*height = max_y;
|
||||
// Crude check to validate that there are no image overlaps/holes for tile
|
||||
// images. Check that the aggregated image area for individual tiles exactly
|
||||
// matches the image area of the constructed canvas. However, the area-match
|
||||
// is necessary but not sufficient condition.
|
||||
if ((flags & TILE_FLAG) && (image_area != (max_x * max_y))) {
|
||||
// Crude check to validate that there are no image overlaps/holes for
|
||||
// fragmented images. Check that the aggregated image area for individual
|
||||
// fragments exactly matches the image area of the constructed canvas.
|
||||
// However, the area-match is necessary but not sufficient condition.
|
||||
if ((flags & FRAGMENTS_FLAG) && (image_area != (max_x * max_y))) {
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
return WEBP_MUX_INVALID_ARGUMENT;
|
||||
@@ -539,8 +539,8 @@ static WebPMuxError CreateVP8XChunk(WebPMux* const mux) {
|
||||
}
|
||||
if (images->header_ != NULL) {
|
||||
if (images->header_->tag_ == kChunks[IDX_FRGM].tag) {
|
||||
// This is a tiled image.
|
||||
flags |= TILE_FLAG;
|
||||
// This is a fragmented image.
|
||||
flags |= FRAGMENTS_FLAG;
|
||||
} else if (images->header_->tag_ == kChunks[IDX_ANMF].tag) {
|
||||
// This is an image with animation.
|
||||
flags |= ANIMATION_FLAG;
|
||||
|
@@ -476,16 +476,16 @@ WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id) {
|
||||
WebPMuxError MuxValidateForImage(const WebPMux* const mux) {
|
||||
const int num_images = MuxImageCount(mux->images_, WEBP_CHUNK_IMAGE);
|
||||
const int num_frames = MuxImageCount(mux->images_, WEBP_CHUNK_ANMF);
|
||||
const int num_tiles = MuxImageCount(mux->images_, WEBP_CHUNK_FRGM);
|
||||
const int num_fragments = MuxImageCount(mux->images_, WEBP_CHUNK_FRGM);
|
||||
|
||||
if (num_images == 0) {
|
||||
// No images in mux.
|
||||
return WEBP_MUX_NOT_FOUND;
|
||||
} else if (num_images == 1 && num_frames == 0 && num_tiles == 0) {
|
||||
} else if (num_images == 1 && num_frames == 0 && num_fragments == 0) {
|
||||
// Valid case (single image).
|
||||
return WEBP_MUX_OK;
|
||||
} else {
|
||||
// Frame/Tile case OR an invalid mux.
|
||||
// Frame/Fragment case OR an invalid mux.
|
||||
return WEBP_MUX_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
@@ -520,7 +520,7 @@ WebPMuxError MuxValidate(const WebPMux* const mux) {
|
||||
int num_xmp;
|
||||
int num_loop_chunks;
|
||||
int num_frames;
|
||||
int num_tiles;
|
||||
int num_fragments;
|
||||
int num_vp8x;
|
||||
int num_images;
|
||||
int num_alpha;
|
||||
@@ -565,8 +565,8 @@ WebPMuxError MuxValidate(const WebPMux* const mux) {
|
||||
}
|
||||
}
|
||||
|
||||
// Tiling: TILE_FLAG and tile chunk(s) are consistent.
|
||||
err = ValidateChunk(mux, IDX_FRGM, TILE_FLAG, flags, -1, &num_tiles);
|
||||
// Fragmentation: FRAGMENTS_FLAG and FRGM chunk(s) are consistent.
|
||||
err = ValidateChunk(mux, IDX_FRGM, FRAGMENTS_FLAG, flags, -1, &num_fragments);
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
|
||||
// Verify either VP8X chunk is present OR there is only one elem in
|
||||
@@ -586,8 +586,8 @@ WebPMuxError MuxValidate(const WebPMux* const mux) {
|
||||
if (err != WEBP_MUX_OK) return err;
|
||||
}
|
||||
|
||||
// num_tiles & num_images are consistent.
|
||||
if (num_tiles > 0 && num_images != num_tiles) {
|
||||
// num_fragments & num_images are consistent.
|
||||
if (num_fragments > 0 && num_images != num_fragments) {
|
||||
return WEBP_MUX_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
@@ -364,19 +364,19 @@ static WebPMuxError MuxGetImageInternal(const WebPMuxImage* const wpi,
|
||||
return SynthesizeBitstream(wpi, &info->bitstream);
|
||||
}
|
||||
|
||||
static WebPMuxError MuxGetFrameTileInternal(const WebPMuxImage* const wpi,
|
||||
WebPMuxFrameInfo* const frame) {
|
||||
static WebPMuxError MuxGetFrameFragmentInternal(const WebPMuxImage* const wpi,
|
||||
WebPMuxFrameInfo* const frame) {
|
||||
const int is_frame = (wpi->header_->tag_ == kChunks[IDX_ANMF].tag);
|
||||
const CHUNK_INDEX idx = is_frame ? IDX_ANMF : IDX_FRGM;
|
||||
const WebPData* frame_tile_data;
|
||||
const WebPData* frame_frgm_data;
|
||||
assert(wpi->header_ != NULL); // Already checked by WebPMuxGetFrame().
|
||||
// Get frame/tile chunk.
|
||||
frame_tile_data = &wpi->header_->data_;
|
||||
if (frame_tile_data->size < kChunks[idx].size) return WEBP_MUX_BAD_DATA;
|
||||
// Get frame/fragment chunk.
|
||||
frame_frgm_data = &wpi->header_->data_;
|
||||
if (frame_frgm_data->size < kChunks[idx].size) return WEBP_MUX_BAD_DATA;
|
||||
// Extract info.
|
||||
frame->x_offset = 2 * GetLE24(frame_tile_data->bytes + 0);
|
||||
frame->y_offset = 2 * GetLE24(frame_tile_data->bytes + 3);
|
||||
frame->duration = is_frame ? 1 + GetLE24(frame_tile_data->bytes + 12) : 1;
|
||||
frame->x_offset = 2 * GetLE24(frame_frgm_data->bytes + 0);
|
||||
frame->y_offset = 2 * GetLE24(frame_frgm_data->bytes + 3);
|
||||
frame->duration = is_frame ? 1 + GetLE24(frame_frgm_data->bytes + 12) : 1;
|
||||
frame->id = ChunkGetIdFromTag(wpi->header_->tag_);
|
||||
return SynthesizeBitstream(wpi, &frame->bitstream);
|
||||
}
|
||||
@@ -399,7 +399,7 @@ WebPMuxError WebPMuxGetFrame(
|
||||
if (wpi->header_ == NULL) {
|
||||
return MuxGetImageInternal(wpi, frame);
|
||||
} else {
|
||||
return MuxGetFrameTileInternal(wpi, frame);
|
||||
return MuxGetFrameFragmentInternal(wpi, frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user