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 |