Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
| 2 // | 2 // |
| 3 // Use of this source code is governed by a BSD-style license | 3 // Use of this source code is governed by a BSD-style license |
| 4 // that can be found in the COPYING file in the root of the source | 4 // that can be found in the COPYING file in the root of the source |
| 5 // tree. An additional intellectual property rights grant can be found | 5 // tree. An additional intellectual property rights grant can be found |
| 6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
| 7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
| 8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
| 9 // | 9 // |
| 10 // WebP container demux. | 10 // WebP container demux. |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 502 if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; | 502 if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; |
| 503 if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR; | 503 if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR; |
| 504 | 504 |
| 505 switch (fourcc) { | 505 switch (fourcc) { |
| 506 case MKFOURCC('V', 'P', '8', 'X'): { | 506 case MKFOURCC('V', 'P', '8', 'X'): { |
| 507 return PARSE_ERROR; | 507 return PARSE_ERROR; |
| 508 } | 508 } |
| 509 case MKFOURCC('A', 'L', 'P', 'H'): | 509 case MKFOURCC('A', 'L', 'P', 'H'): |
| 510 case MKFOURCC('V', 'P', '8', ' '): | 510 case MKFOURCC('V', 'P', '8', ' '): |
| 511 case MKFOURCC('V', 'P', '8', 'L'): { | 511 case MKFOURCC('V', 'P', '8', 'L'): { |
| 512 const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG); | |
|
fbarchard
2013/11/23 01:01:57
!! is obscure.
const int has_frames = dmux->feat
| |
| 512 // check that this isn't an animation (all frames should be in an ANMF). | 513 // check that this isn't an animation (all frames should be in an ANMF). |
| 513 if (anim_chunks > 0) return PARSE_ERROR; | 514 if (anim_chunks > 0 || has_frames) return PARSE_ERROR; |
| 514 | 515 |
| 515 Rewind(mem, CHUNK_HEADER_SIZE); | 516 Rewind(mem, CHUNK_HEADER_SIZE); |
| 516 status = ParseSingleImage(dmux); | 517 status = ParseSingleImage(dmux); |
| 517 break; | 518 break; |
| 518 } | 519 } |
| 519 case MKFOURCC('A', 'N', 'I', 'M'): { | 520 case MKFOURCC('A', 'N', 'I', 'M'): { |
| 520 if (chunk_size_padded < ANIM_CHUNK_SIZE) return PARSE_ERROR; | 521 if (chunk_size_padded < ANIM_CHUNK_SIZE) return PARSE_ERROR; |
| 521 | 522 |
| 522 if (MemDataSize(mem) < chunk_size_padded) { | 523 if (MemDataSize(mem) < chunk_size_padded) { |
| 523 status = PARSE_NEED_MORE_DATA; | 524 status = PARSE_NEED_MORE_DATA; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 592 | 593 |
| 593 if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; | 594 if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; |
| 594 if (dmux->state_ == WEBP_DEMUX_DONE && frame == NULL) return 0; | 595 if (dmux->state_ == WEBP_DEMUX_DONE && frame == NULL) return 0; |
| 595 | 596 |
| 596 if (frame->width_ <= 0 || frame->height_ <= 0) return 0; | 597 if (frame->width_ <= 0 || frame->height_ <= 0) return 0; |
| 597 return 1; | 598 return 1; |
| 598 } | 599 } |
| 599 | 600 |
| 600 // If 'exact' is true, check that the image resolution matches the canvas. | 601 // If 'exact' is true, check that the image resolution matches the canvas. |
| 601 // If 'exact' is false, check that the x/y offsets do not exceed the canvas. | 602 // If 'exact' is false, check that the x/y offsets do not exceed the canvas. |
| 603 // TODO(jzern): this is insufficient in the fragmented image case if the | |
|
fbarchard
2013/11/23 01:01:57
Prefer comments start with uppercase.
This is insu
| |
| 604 // expectation is that the fragments completely cover the canvas. | |
| 602 static int CheckFrameBounds(const Frame* const frame, int exact, | 605 static int CheckFrameBounds(const Frame* const frame, int exact, |
| 603 int canvas_width, int canvas_height) { | 606 int canvas_width, int canvas_height) { |
| 604 if (exact) { | 607 if (exact) { |
| 605 if (frame->x_offset_ != 0 || frame->y_offset_ != 0) { | 608 if (frame->x_offset_ != 0 || frame->y_offset_ != 0) { |
| 606 return 0; | 609 return 0; |
| 607 } | 610 } |
| 608 if (frame->width_ != canvas_width || frame->height_ != canvas_height) { | 611 if (frame->width_ != canvas_width || frame->height_ != canvas_height) { |
| 609 return 0; | 612 return 0; |
| 610 } | 613 } |
| 611 } else { | 614 } else { |
| 612 if (frame->x_offset_ < 0 || frame->y_offset_ < 0) return 0; | 615 if (frame->x_offset_ < 0 || frame->y_offset_ < 0) return 0; |
| 613 if (frame->width_ + frame->x_offset_ > canvas_width) return 0; | 616 if (frame->width_ + frame->x_offset_ > canvas_width) return 0; |
| 614 if (frame->height_ + frame->y_offset_ > canvas_height) return 0; | 617 if (frame->height_ + frame->y_offset_ > canvas_height) return 0; |
| 615 } | 618 } |
| 616 return 1; | 619 return 1; |
| 617 } | 620 } |
| 618 | 621 |
| 619 static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { | 622 static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { |
| 620 const int has_fragments = !!(dmux->feature_flags_ & FRAGMENTS_FLAG); | 623 const int has_fragments = !!(dmux->feature_flags_ & FRAGMENTS_FLAG); |
| 621 const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG); | 624 const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG); |
| 622 const Frame* f = dmux->frames_; | 625 const Frame* f = dmux->frames_; |
| 623 | 626 |
| 624 if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; | 627 if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; |
| 625 | 628 |
| 626 if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; | 629 if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; |
| 627 if (dmux->loop_count_ < 0) return 0; | 630 if (dmux->loop_count_ < 0) return 0; |
| 628 if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0; | 631 if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0; |
| 632 #ifndef WEBP_EXPERIMENTAL_FEATURES | |
| 633 if (has_fragments) return 0; | |
| 634 #endif | |
| 629 | 635 |
| 630 while (f != NULL) { | 636 while (f != NULL) { |
| 631 const int cur_frame_set = f->frame_num_; | 637 const int cur_frame_set = f->frame_num_; |
| 632 int frame_count = 0, fragment_count = 0; | 638 int frame_count = 0, fragment_count = 0; |
| 633 | 639 |
| 634 // Check frame properties and if the image is composed of fragments that | 640 // Check frame properties and if the image is composed of fragments that |
| 635 // each fragment came from a fragment. | 641 // each fragment came from a fragment. |
| 636 for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) { | 642 for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) { |
| 637 const ChunkData* const image = f->img_components_; | 643 const ChunkData* const image = f->img_components_; |
| 638 const ChunkData* const alpha = f->img_components_ + 1; | 644 const ChunkData* const alpha = f->img_components_ + 1; |
| 639 | 645 |
| 646 if (has_fragments && !f->is_fragment_) return 0; | |
| 640 if (!has_fragments && f->is_fragment_) return 0; | 647 if (!has_fragments && f->is_fragment_) return 0; |
| 641 if (!has_frames && f->frame_num_ > 1) return 0; | 648 if (!has_frames && f->frame_num_ > 1) return 0; |
| 649 | |
| 642 if (f->complete_) { | 650 if (f->complete_) { |
| 643 if (alpha->size_ == 0 && image->size_ == 0) return 0; | 651 if (alpha->size_ == 0 && image->size_ == 0) return 0; |
| 644 // Ensure alpha precedes image bitstream. | 652 // Ensure alpha precedes image bitstream. |
| 645 if (alpha->size_ > 0 && alpha->offset_ > image->offset_) { | 653 if (alpha->size_ > 0 && alpha->offset_ > image->offset_) { |
| 646 return 0; | 654 return 0; |
| 647 } | 655 } |
| 648 | 656 |
| 649 if (f->width_ <= 0 || f->height_ <= 0) return 0; | 657 if (f->width_ <= 0 || f->height_ <= 0) return 0; |
| 650 } else { | 658 } else { |
| 651 // There shouldn't be a partial frame in a complete file. | 659 // There shouldn't be a partial frame in a complete file. |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 971 return 0; | 979 return 0; |
| 972 } | 980 } |
| 973 | 981 |
| 974 void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) { | 982 void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) { |
| 975 (void)iter; | 983 (void)iter; |
| 976 } | 984 } |
| 977 | 985 |
| 978 #if defined(__cplusplus) || defined(c_plusplus) | 986 #if defined(__cplusplus) || defined(c_plusplus) |
| 979 } // extern "C" | 987 } // extern "C" |
| 980 #endif | 988 #endif |
| OLD | NEW |