| 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 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 const Frame* const frame = dmux->frames_; | 590 const Frame* const frame = dmux->frames_; |
| 591 if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; | 591 if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; |
| 592 | 592 |
| 593 if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; | 593 if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; |
| 594 if (dmux->state_ == WEBP_DEMUX_DONE && frame == NULL) return 0; | 594 if (dmux->state_ == WEBP_DEMUX_DONE && frame == NULL) return 0; |
| 595 | 595 |
| 596 if (frame->width_ <= 0 || frame->height_ <= 0) return 0; | 596 if (frame->width_ <= 0 || frame->height_ <= 0) return 0; |
| 597 return 1; | 597 return 1; |
| 598 } | 598 } |
| 599 | 599 |
| 600 // 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 static int CheckFrameBounds(const Frame* const frame, int exact, |
| 603 int canvas_width, int canvas_height) { |
| 604 if (exact) { |
| 605 if (frame->x_offset_ != 0 || frame->y_offset_ != 0) { |
| 606 return 0; |
| 607 } |
| 608 if (frame->width_ != canvas_width || frame->height_ != canvas_height) { |
| 609 return 0; |
| 610 } |
| 611 } else { |
| 612 if (frame->x_offset_ < 0 || frame->y_offset_ < 0) return 0; |
| 613 if (frame->width_ + frame->x_offset_ > canvas_width) return 0; |
| 614 if (frame->height_ + frame->y_offset_ > canvas_height) return 0; |
| 615 } |
| 616 return 1; |
| 617 } |
| 618 |
| 600 static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { | 619 static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { |
| 601 const int has_fragments = !!(dmux->feature_flags_ & FRAGMENTS_FLAG); | 620 const int has_fragments = !!(dmux->feature_flags_ & FRAGMENTS_FLAG); |
| 602 const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG); | 621 const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG); |
| 603 const Frame* f; | 622 const Frame* f; |
| 604 | 623 |
| 605 if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; | 624 if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; |
| 606 | 625 |
| 607 if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; | 626 if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; |
| 608 if (dmux->loop_count_ < 0) return 0; | 627 if (dmux->loop_count_ < 0) return 0; |
| 609 if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0; | 628 if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0; |
| 610 | 629 |
| 611 for (f = dmux->frames_; f != NULL; f = f->next_) { | 630 for (f = dmux->frames_; f != NULL; f = f->next_) { |
| 612 const int cur_frame_set = f->frame_num_; | 631 const int cur_frame_set = f->frame_num_; |
| 613 int frame_count = 0, fragment_count = 0; | 632 int frame_count = 0, fragment_count = 0; |
| 614 | 633 |
| 615 // Check frame properties and if the image is composed of fragments that | 634 // Check frame properties and if the image is composed of fragments that |
| 616 // each fragment came from a fragment. | 635 // each fragment came from a fragment. |
| 617 for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) { | 636 for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) { |
| 618 const ChunkData* const image = f->img_components_; | 637 const ChunkData* const image = f->img_components_; |
| 619 const ChunkData* const alpha = f->img_components_ + 1; | 638 const ChunkData* const alpha = f->img_components_ + 1; |
| 620 | 639 |
| 621 if (!has_fragments && f->is_fragment_) return 0; | 640 if (!has_fragments && f->is_fragment_) return 0; |
| 622 if (!has_frames && f->frame_num_ > 1) return 0; | 641 if (!has_frames && f->frame_num_ > 1) return 0; |
| 623 if (f->x_offset_ < 0 || f->y_offset_ < 0) return 0; | |
| 624 if (f->complete_) { | 642 if (f->complete_) { |
| 625 if (alpha->size_ == 0 && image->size_ == 0) return 0; | 643 if (alpha->size_ == 0 && image->size_ == 0) return 0; |
| 626 // Ensure alpha precedes image bitstream. | 644 // Ensure alpha precedes image bitstream. |
| 627 if (alpha->size_ > 0 && alpha->offset_ > image->offset_) { | 645 if (alpha->size_ > 0 && alpha->offset_ > image->offset_) { |
| 628 return 0; | 646 return 0; |
| 629 } | 647 } |
| 630 | 648 |
| 631 if (f->width_ <= 0 || f->height_ <= 0) return 0; | 649 if (f->width_ <= 0 || f->height_ <= 0) return 0; |
| 632 } else { | 650 } else { |
| 633 // There shouldn't be a partial frame in a complete file. | 651 // There shouldn't be a partial frame in a complete file. |
| 634 if (dmux->state_ == WEBP_DEMUX_DONE) return 0; | 652 if (dmux->state_ == WEBP_DEMUX_DONE) return 0; |
| 635 | 653 |
| 636 // Ensure alpha precedes image bitstream. | 654 // Ensure alpha precedes image bitstream. |
| 637 if (alpha->size_ > 0 && image->size_ > 0 && | 655 if (alpha->size_ > 0 && image->size_ > 0 && |
| 638 alpha->offset_ > image->offset_) { | 656 alpha->offset_ > image->offset_) { |
| 639 return 0; | 657 return 0; |
| 640 } | 658 } |
| 641 // There shouldn't be any frames after an incomplete one. | 659 // There shouldn't be any frames after an incomplete one. |
| 642 if (f->next_ != NULL) return 0; | 660 if (f->next_ != NULL) return 0; |
| 643 } | 661 } |
| 644 | 662 |
| 663 if (f->width_ > 0 && f->height_ > 0 && |
| 664 !CheckFrameBounds(f, !(has_frames || has_fragments), |
| 665 dmux->canvas_width_, dmux->canvas_height_)) { |
| 666 return 0; |
| 667 } |
| 668 |
| 645 fragment_count += f->is_fragment_; | 669 fragment_count += f->is_fragment_; |
| 646 ++frame_count; | 670 ++frame_count; |
| 647 } | 671 } |
| 648 if (!has_fragments && frame_count > 1) return 0; | 672 if (!has_fragments && frame_count > 1) return 0; |
| 649 if (fragment_count > 0 && frame_count != fragment_count) return 0; | 673 if (fragment_count > 0 && frame_count != fragment_count) return 0; |
| 650 if (f == NULL) break; | 674 if (f == NULL) break; |
| 651 } | 675 } |
| 652 return 1; | 676 return 1; |
| 653 } | 677 } |
| 654 | 678 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 return 0; | 969 return 0; |
| 946 } | 970 } |
| 947 | 971 |
| 948 void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) { | 972 void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) { |
| 949 (void)iter; | 973 (void)iter; |
| 950 } | 974 } |
| 951 | 975 |
| 952 #if defined(__cplusplus) || defined(c_plusplus) | 976 #if defined(__cplusplus) || defined(c_plusplus) |
| 953 } // extern "C" | 977 } // extern "C" |
| 954 #endif | 978 #endif |
| OLD | NEW |