Merge changes from topic 'demux-fragment-cleanup'

* changes:
  demux: remove GetFragment()
  demux: remove dead fragment related TODO
  demux, Frame: remove is_fragment_ field
  demux,WebPIterator: remove fragment_num/num_fragments
  demux: remove WebPDemuxSelectFragment
This commit is contained in:
James Zern 2015-12-16 06:45:00 +00:00 committed by Gerrit Code Review
commit 791896455a
2 changed files with 25 additions and 75 deletions

View File

@ -47,8 +47,7 @@ typedef struct Frame {
int duration_; int duration_;
WebPMuxAnimDispose dispose_method_; WebPMuxAnimDispose dispose_method_;
WebPMuxAnimBlend blend_method_; WebPMuxAnimBlend blend_method_;
int is_fragment_; // this is a frame fragment (and not a full frame). int frame_num_;
int frame_num_; // the referent frame number for use in assembling fragments.
int complete_; // img_components_ contains a full image. int complete_; // img_components_ contains a full image.
ChunkData img_components_[2]; // 0=VP8{,L} 1=ALPH ChunkData img_components_[2]; // 0=VP8{,L} 1=ALPH
struct Frame* next_; struct Frame* next_;
@ -564,8 +563,6 @@ static int IsValidSimpleFormat(const WebPDemuxer* const dmux) {
// If 'exact' is true, check that the image resolution matches the canvas. // If 'exact' is true, check that the image resolution matches the canvas.
// If 'exact' is false, check that the x/y offsets do not exceed the canvas. // If 'exact' is false, check that the x/y offsets do not exceed the canvas.
// TODO(jzern): this is insufficient in the fragmented image case if the
// expectation is that the fragments completely cover the canvas.
static int CheckFrameBounds(const Frame* const frame, int exact, static int CheckFrameBounds(const Frame* const frame, int exact,
int canvas_width, int canvas_height) { int canvas_width, int canvas_height) {
if (exact) { if (exact) {
@ -597,16 +594,13 @@ static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
while (f != NULL) { while (f != NULL) {
const int cur_frame_set = f->frame_num_; const int cur_frame_set = f->frame_num_;
int frame_count = 0, fragment_count = 0; int frame_count = 0;
// Check frame properties and if the image is composed of fragments that // Check frame properties.
// each fragment came from a fragment.
for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) { for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) {
const ChunkData* const image = f->img_components_; const ChunkData* const image = f->img_components_;
const ChunkData* const alpha = f->img_components_ + 1; const ChunkData* const alpha = f->img_components_ + 1;
if (is_fragmented && !f->is_fragment_) return 0;
if (!is_fragmented && f->is_fragment_) return 0;
if (!is_animation && f->frame_num_ > 1) return 0; if (!is_animation && f->frame_num_ > 1) return 0;
if (f->complete_) { if (f->complete_) {
@ -631,16 +625,13 @@ static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
} }
if (f->width_ > 0 && f->height_ > 0 && if (f->width_ > 0 && f->height_ > 0 &&
!CheckFrameBounds(f, !(is_animation || is_fragmented), !CheckFrameBounds(f, !is_animation,
dmux->canvas_width_, dmux->canvas_height_)) { dmux->canvas_width_, dmux->canvas_height_)) {
return 0; return 0;
} }
fragment_count += f->is_fragment_;
++frame_count; ++frame_count;
} }
if (!is_fragmented && frame_count > 1) return 0;
if (fragment_count > 0 && frame_count != fragment_count) return 0;
} }
return 1; return 1;
} }
@ -746,8 +737,6 @@ uint32_t WebPDemuxGetI(const WebPDemuxer* dmux, WebPFormatFeature feature) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Frame iteration // Frame iteration
// 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) { static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) {
const Frame* f; const Frame* f;
for (f = dmux->frames_; f != NULL; f = f->next_) { for (f = dmux->frames_; f != NULL; f = f->next_) {
@ -756,21 +745,6 @@ static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) {
return f; return f;
} }
// 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* fragment = NULL;
int total;
for (total = 0; f != NULL && f->frame_num_ == this_frame; f = f->next_) {
if (++total == fragment_num) fragment = f;
}
*count = total;
return fragment;
}
static const uint8_t* GetFramePayload(const uint8_t* const mem_buf, static const uint8_t* GetFramePayload(const uint8_t* const mem_buf,
const Frame* const frame, const Frame* const frame,
size_t* const data_size) { size_t* const data_size) {
@ -797,31 +771,25 @@ static const uint8_t* GetFramePayload(const uint8_t* const mem_buf,
// Create a whole 'frame' from VP8 (+ alpha) or lossless. // Create a whole 'frame' from VP8 (+ alpha) or lossless.
static int SynthesizeFrame(const WebPDemuxer* const dmux, static int SynthesizeFrame(const WebPDemuxer* const dmux,
const Frame* const first_frame, const Frame* const frame,
int fragment_num, WebPIterator* const iter) { WebPIterator* const iter) {
const uint8_t* const mem_buf = dmux->mem_.buf_; const uint8_t* const mem_buf = dmux->mem_.buf_;
int num_fragments;
size_t payload_size = 0; size_t payload_size = 0;
const Frame* const fragment = const uint8_t* const payload = GetFramePayload(mem_buf, frame, &payload_size);
GetFragment(first_frame, fragment_num, &num_fragments);
const uint8_t* const payload =
GetFramePayload(mem_buf, fragment, &payload_size);
if (payload == NULL) return 0; if (payload == NULL) return 0;
assert(first_frame != NULL); assert(frame != NULL);
iter->frame_num = first_frame->frame_num_; iter->frame_num = frame->frame_num_;
iter->num_frames = dmux->num_frames_; iter->num_frames = dmux->num_frames_;
iter->fragment_num = fragment_num; iter->x_offset = frame->x_offset_;
iter->num_fragments = num_fragments; iter->y_offset = frame->y_offset_;
iter->x_offset = fragment->x_offset_; iter->width = frame->width_;
iter->y_offset = fragment->y_offset_; iter->height = frame->height_;
iter->width = fragment->width_; iter->has_alpha = frame->has_alpha_;
iter->height = fragment->height_; iter->duration = frame->duration_;
iter->has_alpha = fragment->has_alpha_; iter->dispose_method = frame->dispose_method_;
iter->duration = fragment->duration_; iter->blend_method = frame->blend_method_;
iter->dispose_method = fragment->dispose_method_; iter->complete = frame->complete_;
iter->blend_method = fragment->blend_method_;
iter->complete = fragment->complete_;
iter->fragment.bytes = payload; iter->fragment.bytes = payload;
iter->fragment.size = payload_size; iter->fragment.size = payload_size;
return 1; return 1;
@ -837,7 +805,7 @@ static int SetFrame(int frame_num, WebPIterator* const iter) {
frame = GetFrame(dmux, frame_num); frame = GetFrame(dmux, frame_num);
if (frame == NULL) return 0; if (frame == NULL) return 0;
return SynthesizeFrame(dmux, frame, 1, iter); return SynthesizeFrame(dmux, frame, iter);
} }
int WebPDemuxGetFrame(const WebPDemuxer* dmux, int frame, WebPIterator* iter) { int WebPDemuxGetFrame(const WebPDemuxer* dmux, int frame, WebPIterator* iter) {
@ -859,17 +827,6 @@ int WebPDemuxPrevFrame(WebPIterator* iter) {
return SetFrame(iter->frame_num - 1, iter); return SetFrame(iter->frame_num - 1, iter);
} }
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, fragment_num, iter);
}
return 0;
}
void WebPDemuxReleaseIterator(WebPIterator* iter) { void WebPDemuxReleaseIterator(WebPIterator* iter) {
(void)iter; (void)iter;
} }

View File

@ -55,7 +55,7 @@
extern "C" { extern "C" {
#endif #endif
#define WEBP_DEMUX_ABI_VERSION 0x0105 // MAJOR(8b) + MINOR(8b) #define WEBP_DEMUX_ABI_VERSION 0x0107 // MAJOR(8b) + MINOR(8b)
// Note: forward declaring enumerations is not allowed in (strict) C and C++, // Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference. // the types are left here for reference.
@ -137,17 +137,15 @@ WEBP_EXTERN(uint32_t) WebPDemuxGetI(
struct WebPIterator { struct WebPIterator {
int frame_num; int frame_num;
int num_frames; // equivalent to WEBP_FF_FRAME_COUNT. int num_frames; // equivalent to WEBP_FF_FRAME_COUNT.
int fragment_num;
int num_fragments;
int x_offset, y_offset; // offset relative to the canvas. int x_offset, y_offset; // offset relative to the canvas.
int width, height; // dimensions of this frame or fragment. int width, height; // dimensions of this frame.
int duration; // display duration in milliseconds. int duration; // display duration in milliseconds.
WebPMuxAnimDispose dispose_method; // dispose method for the frame. WebPMuxAnimDispose dispose_method; // dispose method for the frame.
int complete; // true if 'fragment' contains a full frame. partial images int complete; // true if 'fragment' contains a full frame. partial images
// may still be decoded with the WebP incremental decoder. // may still be decoded with the WebP incremental decoder.
WebPData fragment; // The frame or fragment given by 'frame_num' and WebPData fragment; // The frame given by 'frame_num'. Note for historical
// 'fragment_num'. // reasons this is called a fragment.
int has_alpha; // True if the frame or fragment contains transparency. int has_alpha; // True if the frame contains transparency.
WebPMuxAnimBlend blend_method; // Blend operation for the frame. WebPMuxAnimBlend blend_method; // Blend operation for the frame.
uint32_t pad[2]; // padding for later use. uint32_t pad[2]; // padding for later use.
@ -155,8 +153,7 @@ struct WebPIterator {
}; };
// Retrieves frame 'frame_number' from 'dmux'. // Retrieves frame 'frame_number' from 'dmux'.
// 'iter->fragment' points to the first fragment on return from this function. // 'iter->fragment' points to the frame on return from this function.
// Individual fragments may be extracted using WebPDemuxSelectFragment().
// Setting 'frame_number' equal to 0 will return the last frame of the image. // Setting 'frame_number' equal to 0 will return the last frame of the image.
// Returns false if 'dmux' is NULL or frame 'frame_number' is not present. // Returns false if 'dmux' is NULL or frame 'frame_number' is not present.
// Call WebPDemuxReleaseIterator() when use of the iterator is complete. // Call WebPDemuxReleaseIterator() when use of the iterator is complete.
@ -170,10 +167,6 @@ WEBP_EXTERN(int) WebPDemuxGetFrame(
WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter); WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter);
WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter); WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter);
// Sets 'iter->fragment' to reflect fragment number 'fragment_num'.
// Returns true if fragment 'fragment_num' is present, false otherwise.
WEBP_EXTERN(int) WebPDemuxSelectFragment(WebPIterator* iter, int fragment_num);
// Releases any memory associated with 'iter'. // Releases any memory associated with 'iter'.
// Must be called before any subsequent calls to WebPDemuxGetChunk() on the same // Must be called before any subsequent calls to WebPDemuxGetChunk() on the same
// iter. Also, must be called before destroying the associated WebPDemuxer with // iter. Also, must be called before destroying the associated WebPDemuxer with