Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: third_party/libwebp/dec/vp8l.c

Issue 2149863002: libwebp: update to v0.5.1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libwebp/dec/vp8i.h ('k') | third_party/libwebp/dec/vp8li.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // main entry for the decoder 10 // main entry for the decoder
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 // Inverse transforms. 707 // Inverse transforms.
708 // TODO: most transforms only need to operate on the cropped region only. 708 // TODO: most transforms only need to operate on the cropped region only.
709 memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out)); 709 memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out));
710 while (n-- > 0) { 710 while (n-- > 0) {
711 VP8LTransform* const transform = &dec->transforms_[n]; 711 VP8LTransform* const transform = &dec->transforms_[n];
712 VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out); 712 VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out);
713 rows_in = rows_out; 713 rows_in = rows_out;
714 } 714 }
715 } 715 }
716 716
717 // Special method for paletted alpha data.
718 static void ApplyInverseTransformsAlpha(VP8LDecoder* const dec, int num_rows,
719 const uint8_t* const rows) {
720 const int start_row = dec->last_row_;
721 const int end_row = start_row + num_rows;
722 const uint8_t* rows_in = rows;
723 uint8_t* rows_out = (uint8_t*)dec->io_->opaque + dec->io_->width * start_row;
724 VP8LTransform* const transform = &dec->transforms_[0];
725 assert(dec->next_transform_ == 1);
726 assert(transform->type_ == COLOR_INDEXING_TRANSFORM);
727 VP8LColorIndexInverseTransformAlpha(transform, start_row, end_row, rows_in,
728 rows_out);
729 }
730
731 // Processes (transforms, scales & color-converts) the rows decoded after the 717 // Processes (transforms, scales & color-converts) the rows decoded after the
732 // last call. 718 // last call.
733 static void ProcessRows(VP8LDecoder* const dec, int row) { 719 static void ProcessRows(VP8LDecoder* const dec, int row) {
734 const uint32_t* const rows = dec->pixels_ + dec->width_ * dec->last_row_; 720 const uint32_t* const rows = dec->pixels_ + dec->width_ * dec->last_row_;
735 const int num_rows = row - dec->last_row_; 721 const int num_rows = row - dec->last_row_;
736 722
737 if (num_rows <= 0) return; // Nothing to be done. 723 assert(row <= dec->io_->crop_bottom);
738 ApplyInverseTransforms(dec, num_rows, rows); 724 // We can't process more than NUM_ARGB_CACHE_ROWS at a time (that's the size
739 725 // of argb_cache_), but we currently don't need more than that.
740 // Emit output. 726 assert(num_rows <= NUM_ARGB_CACHE_ROWS);
741 { 727 if (num_rows > 0) { // Emit output.
742 VP8Io* const io = dec->io_; 728 VP8Io* const io = dec->io_;
743 uint8_t* rows_data = (uint8_t*)dec->argb_cache_; 729 uint8_t* rows_data = (uint8_t*)dec->argb_cache_;
744 const int in_stride = io->width * sizeof(uint32_t); // in unit of RGBA 730 const int in_stride = io->width * sizeof(uint32_t); // in unit of RGBA
731
732 ApplyInverseTransforms(dec, num_rows, rows);
745 if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) { 733 if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) {
746 // Nothing to output (this time). 734 // Nothing to output (this time).
747 } else { 735 } else {
748 const WebPDecBuffer* const output = dec->output_; 736 const WebPDecBuffer* const output = dec->output_;
749 if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA 737 if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA
750 const WebPRGBABuffer* const buf = &output->u.RGBA; 738 const WebPRGBABuffer* const buf = &output->u.RGBA;
751 uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride; 739 uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
752 const int num_rows_out = io->use_scaling ? 740 const int num_rows_out = io->use_scaling ?
753 EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h, 741 EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h,
754 rgba, buf->stride) : 742 rgba, buf->stride) :
(...skipping 24 matching lines...) Expand all
779 // call to ReadSymbol() for red/blue/alpha channels. 767 // call to ReadSymbol() for red/blue/alpha channels.
780 for (i = 0; i < hdr->num_htree_groups_; ++i) { 768 for (i = 0; i < hdr->num_htree_groups_; ++i) {
781 HuffmanCode** const htrees = hdr->htree_groups_[i].htrees; 769 HuffmanCode** const htrees = hdr->htree_groups_[i].htrees;
782 if (htrees[RED][0].bits > 0) return 0; 770 if (htrees[RED][0].bits > 0) return 0;
783 if (htrees[BLUE][0].bits > 0) return 0; 771 if (htrees[BLUE][0].bits > 0) return 0;
784 if (htrees[ALPHA][0].bits > 0) return 0; 772 if (htrees[ALPHA][0].bits > 0) return 0;
785 } 773 }
786 return 1; 774 return 1;
787 } 775 }
788 776
789 static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int row) { 777 static void AlphaApplyFilter(ALPHDecoder* const alph_dec,
790 const int num_rows = row - dec->last_row_; 778 int first_row, int last_row,
791 const uint8_t* const in = 779 uint8_t* out, int stride) {
792 (uint8_t*)dec->pixels_ + dec->width_ * dec->last_row_; 780 if (alph_dec->filter_ != WEBP_FILTER_NONE) {
793 if (num_rows > 0) { 781 int y;
794 ApplyInverseTransformsAlpha(dec, num_rows, in); 782 const uint8_t* prev_line = alph_dec->prev_line_;
783 assert(WebPUnfilters[alph_dec->filter_] != NULL);
784 for (y = first_row; y < last_row; ++y) {
785 WebPUnfilters[alph_dec->filter_](prev_line, out, out, stride);
786 prev_line = out;
787 out += stride;
788 }
789 alph_dec->prev_line_ = prev_line;
795 } 790 }
796 dec->last_row_ = dec->last_out_row_ = row; 791 }
792
793 static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int last_row) {
794 // For vertical and gradient filtering, we need to decode the part above the
795 // crop_top row, in order to have the correct spatial predictors.
796 ALPHDecoder* const alph_dec = (ALPHDecoder*)dec->io_->opaque;
797 const int top_row =
798 (alph_dec->filter_ == WEBP_FILTER_NONE ||
799 alph_dec->filter_ == WEBP_FILTER_HORIZONTAL) ? dec->io_->crop_top
800 : dec->last_row_;
801 const int first_row = (dec->last_row_ < top_row) ? top_row : dec->last_row_;
802 assert(last_row <= dec->io_->crop_bottom);
803 if (last_row > first_row) {
804 // Special method for paletted alpha data. We only process the cropped area.
805 const int width = dec->io_->width;
806 uint8_t* out = alph_dec->output_ + width * first_row;
807 const uint8_t* const in =
808 (uint8_t*)dec->pixels_ + dec->width_ * first_row;
809 VP8LTransform* const transform = &dec->transforms_[0];
810 assert(dec->next_transform_ == 1);
811 assert(transform->type_ == COLOR_INDEXING_TRANSFORM);
812 VP8LColorIndexInverseTransformAlpha(transform, first_row, last_row,
813 in, out);
814 AlphaApplyFilter(alph_dec, first_row, last_row, out, width);
815 }
816 dec->last_row_ = dec->last_out_row_ = last_row;
797 } 817 }
798 818
799 //------------------------------------------------------------------------------ 819 //------------------------------------------------------------------------------
800 // Helper functions for fast pattern copy (8b and 32b) 820 // Helper functions for fast pattern copy (8b and 32b)
801 821
802 // cyclic rotation of pattern word 822 // cyclic rotation of pattern word
803 static WEBP_INLINE uint32_t Rotate8b(uint32_t V) { 823 static WEBP_INLINE uint32_t Rotate8b(uint32_t V) {
804 #if defined(WORDS_BIGENDIAN) 824 #if defined(WORDS_BIGENDIAN)
805 return ((V & 0xff000000u) >> 24) | (V << 8); 825 return ((V & 0xff000000u) >> 24) | (V << 8);
806 #else 826 #else
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 935
916 //------------------------------------------------------------------------------ 936 //------------------------------------------------------------------------------
917 937
918 static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data, 938 static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
919 int width, int height, int last_row) { 939 int width, int height, int last_row) {
920 int ok = 1; 940 int ok = 1;
921 int row = dec->last_pixel_ / width; 941 int row = dec->last_pixel_ / width;
922 int col = dec->last_pixel_ % width; 942 int col = dec->last_pixel_ % width;
923 VP8LBitReader* const br = &dec->br_; 943 VP8LBitReader* const br = &dec->br_;
924 VP8LMetadata* const hdr = &dec->hdr_; 944 VP8LMetadata* const hdr = &dec->hdr_;
925 const HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row);
926 int pos = dec->last_pixel_; // current position 945 int pos = dec->last_pixel_; // current position
927 const int end = width * height; // End of data 946 const int end = width * height; // End of data
928 const int last = width * last_row; // Last pixel to decode 947 const int last = width * last_row; // Last pixel to decode
929 const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; 948 const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
930 const int mask = hdr->huffman_mask_; 949 const int mask = hdr->huffman_mask_;
931 assert(htree_group != NULL); 950 const HTreeGroup* htree_group =
932 assert(pos < end); 951 (pos < last) ? GetHtreeGroupForPos(hdr, col, row) : NULL;
952 assert(pos <= end);
933 assert(last_row <= height); 953 assert(last_row <= height);
934 assert(Is8bOptimizable(hdr)); 954 assert(Is8bOptimizable(hdr));
935 955
936 while (!br->eos_ && pos < last) { 956 while (!br->eos_ && pos < last) {
937 int code; 957 int code;
938 // Only update when changing tile. 958 // Only update when changing tile.
939 if ((col & mask) == 0) { 959 if ((col & mask) == 0) {
940 htree_group = GetHtreeGroupForPos(hdr, col, row); 960 htree_group = GetHtreeGroupForPos(hdr, col, row);
941 } 961 }
962 assert(htree_group != NULL);
942 VP8LFillBitWindow(br); 963 VP8LFillBitWindow(br);
943 code = ReadSymbol(htree_group->htrees[GREEN], br); 964 code = ReadSymbol(htree_group->htrees[GREEN], br);
944 if (code < NUM_LITERAL_CODES) { // Literal 965 if (code < NUM_LITERAL_CODES) { // Literal
945 data[pos] = code; 966 data[pos] = code;
946 ++pos; 967 ++pos;
947 ++col; 968 ++col;
948 if (col >= width) { 969 if (col >= width) {
949 col = 0; 970 col = 0;
950 ++row; 971 ++row;
951 if (row % NUM_ARGB_CACHE_ROWS == 0) { 972 if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
952 ExtractPalettedAlphaRows(dec, row); 973 ExtractPalettedAlphaRows(dec, row);
953 } 974 }
954 } 975 }
955 } else if (code < len_code_limit) { // Backward reference 976 } else if (code < len_code_limit) { // Backward reference
956 int dist_code, dist; 977 int dist_code, dist;
957 const int length_sym = code - NUM_LITERAL_CODES; 978 const int length_sym = code - NUM_LITERAL_CODES;
958 const int length = GetCopyLength(length_sym, br); 979 const int length = GetCopyLength(length_sym, br);
959 const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br); 980 const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br);
960 VP8LFillBitWindow(br); 981 VP8LFillBitWindow(br);
961 dist_code = GetCopyDistance(dist_symbol, br); 982 dist_code = GetCopyDistance(dist_symbol, br);
962 dist = PlaneCodeToDistance(width, dist_code); 983 dist = PlaneCodeToDistance(width, dist_code);
963 if (pos >= dist && end - pos >= length) { 984 if (pos >= dist && end - pos >= length) {
964 CopyBlock8b(data + pos, dist, length); 985 CopyBlock8b(data + pos, dist, length);
965 } else { 986 } else {
966 ok = 0; 987 ok = 0;
967 goto End; 988 goto End;
968 } 989 }
969 pos += length; 990 pos += length;
970 col += length; 991 col += length;
971 while (col >= width) { 992 while (col >= width) {
972 col -= width; 993 col -= width;
973 ++row; 994 ++row;
974 if (row % NUM_ARGB_CACHE_ROWS == 0) { 995 if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
975 ExtractPalettedAlphaRows(dec, row); 996 ExtractPalettedAlphaRows(dec, row);
976 } 997 }
977 } 998 }
978 if (pos < last && (col & mask)) { 999 if (pos < last && (col & mask)) {
979 htree_group = GetHtreeGroupForPos(hdr, col, row); 1000 htree_group = GetHtreeGroupForPos(hdr, col, row);
980 } 1001 }
981 } else { // Not reached 1002 } else { // Not reached
982 ok = 0; 1003 ok = 0;
983 goto End; 1004 goto End;
984 } 1005 }
985 assert(br->eos_ == VP8LIsEndOfStream(br)); 1006 assert(br->eos_ == VP8LIsEndOfStream(br));
986 } 1007 }
987 // Process the remaining rows corresponding to last row-block. 1008 // Process the remaining rows corresponding to last row-block.
988 ExtractPalettedAlphaRows(dec, row); 1009 ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row);
989 1010
990 End: 1011 End:
991 if (!ok || (br->eos_ && pos < end)) { 1012 if (!ok || (br->eos_ && pos < end)) {
992 ok = 0; 1013 ok = 0;
993 dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED 1014 dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED
994 : VP8_STATUS_BITSTREAM_ERROR; 1015 : VP8_STATUS_BITSTREAM_ERROR;
995 } else { 1016 } else {
996 dec->last_pixel_ = pos; 1017 dec->last_pixel_ = pos;
997 } 1018 }
998 return ok; 1019 return ok;
(...skipping 19 matching lines...) Expand all
1018 } 1039 }
1019 1040
1020 #define SYNC_EVERY_N_ROWS 8 // minimum number of rows between check-points 1041 #define SYNC_EVERY_N_ROWS 8 // minimum number of rows between check-points
1021 static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data, 1042 static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
1022 int width, int height, int last_row, 1043 int width, int height, int last_row,
1023 ProcessRowsFunc process_func) { 1044 ProcessRowsFunc process_func) {
1024 int row = dec->last_pixel_ / width; 1045 int row = dec->last_pixel_ / width;
1025 int col = dec->last_pixel_ % width; 1046 int col = dec->last_pixel_ % width;
1026 VP8LBitReader* const br = &dec->br_; 1047 VP8LBitReader* const br = &dec->br_;
1027 VP8LMetadata* const hdr = &dec->hdr_; 1048 VP8LMetadata* const hdr = &dec->hdr_;
1028 HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row);
1029 uint32_t* src = data + dec->last_pixel_; 1049 uint32_t* src = data + dec->last_pixel_;
1030 uint32_t* last_cached = src; 1050 uint32_t* last_cached = src;
1031 uint32_t* const src_end = data + width * height; // End of data 1051 uint32_t* const src_end = data + width * height; // End of data
1032 uint32_t* const src_last = data + width * last_row; // Last pixel to decode 1052 uint32_t* const src_last = data + width * last_row; // Last pixel to decode
1033 const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; 1053 const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
1034 const int color_cache_limit = len_code_limit + hdr->color_cache_size_; 1054 const int color_cache_limit = len_code_limit + hdr->color_cache_size_;
1035 int next_sync_row = dec->incremental_ ? row : 1 << 24; 1055 int next_sync_row = dec->incremental_ ? row : 1 << 24;
1036 VP8LColorCache* const color_cache = 1056 VP8LColorCache* const color_cache =
1037 (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL; 1057 (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL;
1038 const int mask = hdr->huffman_mask_; 1058 const int mask = hdr->huffman_mask_;
1039 assert(htree_group != NULL); 1059 const HTreeGroup* htree_group =
1040 assert(src < src_end); 1060 (src < src_last) ? GetHtreeGroupForPos(hdr, col, row) : NULL;
1061 assert(dec->last_row_ < last_row);
1041 assert(src_last <= src_end); 1062 assert(src_last <= src_end);
1042 1063
1043 while (src < src_last) { 1064 while (src < src_last) {
1044 int code; 1065 int code;
1045 if (row >= next_sync_row) { 1066 if (row >= next_sync_row) {
1046 SaveState(dec, (int)(src - data)); 1067 SaveState(dec, (int)(src - data));
1047 next_sync_row = row + SYNC_EVERY_N_ROWS; 1068 next_sync_row = row + SYNC_EVERY_N_ROWS;
1048 } 1069 }
1049 // Only update when changing tile. Note we could use this test: 1070 // Only update when changing tile. Note we could use this test:
1050 // if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed 1071 // if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed
1051 // but that's actually slower and needs storing the previous col/row. 1072 // but that's actually slower and needs storing the previous col/row.
1052 if ((col & mask) == 0) htree_group = GetHtreeGroupForPos(hdr, col, row); 1073 if ((col & mask) == 0) {
1074 htree_group = GetHtreeGroupForPos(hdr, col, row);
1075 }
1076 assert(htree_group != NULL);
1053 if (htree_group->is_trivial_code) { 1077 if (htree_group->is_trivial_code) {
1054 *src = htree_group->literal_arb; 1078 *src = htree_group->literal_arb;
1055 goto AdvanceByOne; 1079 goto AdvanceByOne;
1056 } 1080 }
1057 VP8LFillBitWindow(br); 1081 VP8LFillBitWindow(br);
1058 if (htree_group->use_packed_table) { 1082 if (htree_group->use_packed_table) {
1059 code = ReadPackedSymbols(htree_group, br, src); 1083 code = ReadPackedSymbols(htree_group, br, src);
1060 if (code == PACKED_NON_LITERAL_CODE) goto AdvanceByOne; 1084 if (code == PACKED_NON_LITERAL_CODE) goto AdvanceByOne;
1061 } else { 1085 } else {
1062 code = ReadSymbol(htree_group->htrees[GREEN], br); 1086 code = ReadSymbol(htree_group->htrees[GREEN], br);
(...skipping 10 matching lines...) Expand all
1073 alpha = ReadSymbol(htree_group->htrees[ALPHA], br); 1097 alpha = ReadSymbol(htree_group->htrees[ALPHA], br);
1074 if (br->eos_) break; 1098 if (br->eos_) break;
1075 *src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue; 1099 *src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue;
1076 } 1100 }
1077 AdvanceByOne: 1101 AdvanceByOne:
1078 ++src; 1102 ++src;
1079 ++col; 1103 ++col;
1080 if (col >= width) { 1104 if (col >= width) {
1081 col = 0; 1105 col = 0;
1082 ++row; 1106 ++row;
1083 if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) { 1107 if (process_func != NULL) {
1084 process_func(dec, row); 1108 if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
1109 process_func(dec, row);
1110 }
1085 } 1111 }
1086 if (color_cache != NULL) { 1112 if (color_cache != NULL) {
1087 while (last_cached < src) { 1113 while (last_cached < src) {
1088 VP8LColorCacheInsert(color_cache, *last_cached++); 1114 VP8LColorCacheInsert(color_cache, *last_cached++);
1089 } 1115 }
1090 } 1116 }
1091 } 1117 }
1092 } else if (code < len_code_limit) { // Backward reference 1118 } else if (code < len_code_limit) { // Backward reference
1093 int dist_code, dist; 1119 int dist_code, dist;
1094 const int length_sym = code - NUM_LITERAL_CODES; 1120 const int length_sym = code - NUM_LITERAL_CODES;
1095 const int length = GetCopyLength(length_sym, br); 1121 const int length = GetCopyLength(length_sym, br);
1096 const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br); 1122 const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br);
1097 VP8LFillBitWindow(br); 1123 VP8LFillBitWindow(br);
1098 dist_code = GetCopyDistance(dist_symbol, br); 1124 dist_code = GetCopyDistance(dist_symbol, br);
1099 dist = PlaneCodeToDistance(width, dist_code); 1125 dist = PlaneCodeToDistance(width, dist_code);
1100 if (br->eos_) break; 1126 if (br->eos_) break;
1101 if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) { 1127 if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) {
1102 goto Error; 1128 goto Error;
1103 } else { 1129 } else {
1104 CopyBlock32b(src, dist, length); 1130 CopyBlock32b(src, dist, length);
1105 } 1131 }
1106 src += length; 1132 src += length;
1107 col += length; 1133 col += length;
1108 while (col >= width) { 1134 while (col >= width) {
1109 col -= width; 1135 col -= width;
1110 ++row; 1136 ++row;
1111 if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) { 1137 if (process_func != NULL) {
1112 process_func(dec, row); 1138 if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
1139 process_func(dec, row);
1140 }
1113 } 1141 }
1114 } 1142 }
1115 // Because of the check done above (before 'src' was incremented by 1143 // Because of the check done above (before 'src' was incremented by
1116 // 'length'), the following holds true. 1144 // 'length'), the following holds true.
1117 assert(src <= src_end); 1145 assert(src <= src_end);
1118 if (col & mask) htree_group = GetHtreeGroupForPos(hdr, col, row); 1146 if (col & mask) htree_group = GetHtreeGroupForPos(hdr, col, row);
1119 if (color_cache != NULL) { 1147 if (color_cache != NULL) {
1120 while (last_cached < src) { 1148 while (last_cached < src) {
1121 VP8LColorCacheInsert(color_cache, *last_cached++); 1149 VP8LColorCacheInsert(color_cache, *last_cached++);
1122 } 1150 }
(...skipping 10 matching lines...) Expand all
1133 goto Error; 1161 goto Error;
1134 } 1162 }
1135 assert(br->eos_ == VP8LIsEndOfStream(br)); 1163 assert(br->eos_ == VP8LIsEndOfStream(br));
1136 } 1164 }
1137 1165
1138 if (dec->incremental_ && br->eos_ && src < src_end) { 1166 if (dec->incremental_ && br->eos_ && src < src_end) {
1139 RestoreState(dec); 1167 RestoreState(dec);
1140 } else if (!br->eos_) { 1168 } else if (!br->eos_) {
1141 // Process the remaining rows corresponding to last row-block. 1169 // Process the remaining rows corresponding to last row-block.
1142 if (process_func != NULL) { 1170 if (process_func != NULL) {
1143 process_func(dec, row); 1171 process_func(dec, row > last_row ? last_row : row);
1144 } 1172 }
1145 dec->status_ = VP8_STATUS_OK; 1173 dec->status_ = VP8_STATUS_OK;
1146 dec->last_pixel_ = (int)(src - data); // end-of-scan marker 1174 dec->last_pixel_ = (int)(src - data); // end-of-scan marker
1147 } else { 1175 } else {
1148 // if not incremental, and we are past the end of buffer (eos_=1), then this 1176 // if not incremental, and we are past the end of buffer (eos_=1), then this
1149 // is a real bitstream error. 1177 // is a real bitstream error.
1150 goto Error; 1178 goto Error;
1151 } 1179 }
1152 return 1; 1180 return 1;
1153 1181
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 if (dec->pixels_ == NULL) { 1459 if (dec->pixels_ == NULL) {
1432 dec->status_ = VP8_STATUS_OUT_OF_MEMORY; 1460 dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
1433 return 0; 1461 return 0;
1434 } 1462 }
1435 return 1; 1463 return 1;
1436 } 1464 }
1437 1465
1438 //------------------------------------------------------------------------------ 1466 //------------------------------------------------------------------------------
1439 1467
1440 // Special row-processing that only stores the alpha data. 1468 // Special row-processing that only stores the alpha data.
1441 static void ExtractAlphaRows(VP8LDecoder* const dec, int row) { 1469 static void ExtractAlphaRows(VP8LDecoder* const dec, int last_row) {
1442 const int num_rows = row - dec->last_row_; 1470 int cur_row = dec->last_row_;
1443 const uint32_t* const in = dec->pixels_ + dec->width_ * dec->last_row_; 1471 int num_rows = last_row - cur_row;
1472 const uint32_t* in = dec->pixels_ + dec->width_ * cur_row;
1444 1473
1445 if (num_rows <= 0) return; // Nothing to be done. 1474 assert(last_row <= dec->io_->crop_bottom);
1446 ApplyInverseTransforms(dec, num_rows, in); 1475 while (num_rows > 0) {
1447 1476 const int num_rows_to_process =
1448 // Extract alpha (which is stored in the green plane). 1477 (num_rows > NUM_ARGB_CACHE_ROWS) ? NUM_ARGB_CACHE_ROWS : num_rows;
1449 { 1478 // Extract alpha (which is stored in the green plane).
1479 ALPHDecoder* const alph_dec = (ALPHDecoder*)dec->io_->opaque;
1480 uint8_t* const output = alph_dec->output_;
1450 const int width = dec->io_->width; // the final width (!= dec->width_) 1481 const int width = dec->io_->width; // the final width (!= dec->width_)
1451 const int cache_pixs = width * num_rows; 1482 const int cache_pixs = width * num_rows_to_process;
1452 uint8_t* const dst = (uint8_t*)dec->io_->opaque + width * dec->last_row_; 1483 uint8_t* const dst = output + width * cur_row;
1453 const uint32_t* const src = dec->argb_cache_; 1484 const uint32_t* const src = dec->argb_cache_;
1454 int i; 1485 int i;
1486 ApplyInverseTransforms(dec, num_rows_to_process, in);
1455 for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff; 1487 for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff;
1488 AlphaApplyFilter(alph_dec,
1489 cur_row, cur_row + num_rows_to_process, dst, width);
1490 num_rows -= num_rows_to_process;
1491 in += num_rows_to_process * dec->width_;
1492 cur_row += num_rows_to_process;
1456 } 1493 }
1457 dec->last_row_ = dec->last_out_row_ = row; 1494 assert(cur_row == last_row);
1495 dec->last_row_ = dec->last_out_row_ = last_row;
1458 } 1496 }
1459 1497
1460 int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec, 1498 int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec,
1461 const uint8_t* const data, size_t data_size, 1499 const uint8_t* const data, size_t data_size) {
1462 uint8_t* const output) {
1463 int ok = 0; 1500 int ok = 0;
1464 VP8LDecoder* dec; 1501 VP8LDecoder* dec = VP8LNew();
1465 VP8Io* io; 1502
1503 if (dec == NULL) return 0;
1504
1466 assert(alph_dec != NULL); 1505 assert(alph_dec != NULL);
1467 alph_dec->vp8l_dec_ = VP8LNew(); 1506 alph_dec->vp8l_dec_ = dec;
1468 if (alph_dec->vp8l_dec_ == NULL) return 0;
1469 dec = alph_dec->vp8l_dec_;
1470 1507
1471 dec->width_ = alph_dec->width_; 1508 dec->width_ = alph_dec->width_;
1472 dec->height_ = alph_dec->height_; 1509 dec->height_ = alph_dec->height_;
1473 dec->io_ = &alph_dec->io_; 1510 dec->io_ = &alph_dec->io_;
1474 io = dec->io_; 1511 dec->io_->opaque = alph_dec;
1475 1512 dec->io_->width = alph_dec->width_;
1476 VP8InitIo(io); 1513 dec->io_->height = alph_dec->height_;
1477 WebPInitCustomIo(NULL, io); // Just a sanity Init. io won't be used.
1478 io->opaque = output;
1479 io->width = alph_dec->width_;
1480 io->height = alph_dec->height_;
1481 1514
1482 dec->status_ = VP8_STATUS_OK; 1515 dec->status_ = VP8_STATUS_OK;
1483 VP8LInitBitReader(&dec->br_, data, data_size); 1516 VP8LInitBitReader(&dec->br_, data, data_size);
1484 1517
1485 if (!DecodeImageStream(alph_dec->width_, alph_dec->height_, 1, dec, NULL)) { 1518 if (!DecodeImageStream(alph_dec->width_, alph_dec->height_, 1, dec, NULL)) {
1486 goto Err; 1519 goto Err;
1487 } 1520 }
1488 1521
1489 // Special case: if alpha data uses only the color indexing transform and 1522 // Special case: if alpha data uses only the color indexing transform and
1490 // doesn't use color cache (a frequent case), we will use DecodeAlphaData() 1523 // doesn't use color cache (a frequent case), we will use DecodeAlphaData()
1491 // method that only needs allocation of 1 byte per pixel (alpha channel). 1524 // method that only needs allocation of 1 byte per pixel (alpha channel).
1492 if (dec->next_transform_ == 1 && 1525 if (dec->next_transform_ == 1 &&
1493 dec->transforms_[0].type_ == COLOR_INDEXING_TRANSFORM && 1526 dec->transforms_[0].type_ == COLOR_INDEXING_TRANSFORM &&
1494 Is8bOptimizable(&dec->hdr_)) { 1527 Is8bOptimizable(&dec->hdr_)) {
1495 alph_dec->use_8b_decode = 1; 1528 alph_dec->use_8b_decode_ = 1;
1496 ok = AllocateInternalBuffers8b(dec); 1529 ok = AllocateInternalBuffers8b(dec);
1497 } else { 1530 } else {
1498 // Allocate internal buffers (note that dec->width_ may have changed here). 1531 // Allocate internal buffers (note that dec->width_ may have changed here).
1499 alph_dec->use_8b_decode = 0; 1532 alph_dec->use_8b_decode_ = 0;
1500 ok = AllocateInternalBuffers32b(dec, alph_dec->width_); 1533 ok = AllocateInternalBuffers32b(dec, alph_dec->width_);
1501 } 1534 }
1502 1535
1503 if (!ok) goto Err; 1536 if (!ok) goto Err;
1504 1537
1505 return 1; 1538 return 1;
1506 1539
1507 Err: 1540 Err:
1508 VP8LDelete(alph_dec->vp8l_dec_); 1541 VP8LDelete(alph_dec->vp8l_dec_);
1509 alph_dec->vp8l_dec_ = NULL; 1542 alph_dec->vp8l_dec_ = NULL;
1510 return 0; 1543 return 0;
1511 } 1544 }
1512 1545
1513 int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) { 1546 int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) {
1514 VP8LDecoder* const dec = alph_dec->vp8l_dec_; 1547 VP8LDecoder* const dec = alph_dec->vp8l_dec_;
1515 assert(dec != NULL); 1548 assert(dec != NULL);
1516 assert(last_row <= dec->height_); 1549 assert(last_row <= dec->height_);
1517 1550
1518 if (dec->last_pixel_ == dec->width_ * dec->height_) { 1551 if (dec->last_row_ >= last_row) {
1519 return 1; // done 1552 return 1; // done
1520 } 1553 }
1521 1554
1522 // Decode (with special row processing). 1555 // Decode (with special row processing).
1523 return alph_dec->use_8b_decode ? 1556 return alph_dec->use_8b_decode_ ?
1524 DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_, 1557 DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_,
1525 last_row) : 1558 last_row) :
1526 DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_, 1559 DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_,
1527 last_row, ExtractAlphaRows); 1560 last_row, ExtractAlphaRows);
1528 } 1561 }
1529 1562
1530 //------------------------------------------------------------------------------ 1563 //------------------------------------------------------------------------------
1531 1564
1532 int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io) { 1565 int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io) {
1533 int width, height, has_alpha; 1566 int width, height, has_alpha;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 dec->status_ = VP8_STATUS_OUT_OF_MEMORY; 1637 dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
1605 goto Err; 1638 goto Err;
1606 } 1639 }
1607 } 1640 }
1608 } 1641 }
1609 dec->state_ = READ_DATA; 1642 dec->state_ = READ_DATA;
1610 } 1643 }
1611 1644
1612 // Decode. 1645 // Decode.
1613 if (!DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_, 1646 if (!DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_,
1614 dec->height_, ProcessRows)) { 1647 io->crop_bottom, ProcessRows)) {
1615 goto Err; 1648 goto Err;
1616 } 1649 }
1617 1650
1618 params->last_y = dec->last_out_row_; 1651 params->last_y = dec->last_out_row_;
1619 return 1; 1652 return 1;
1620 1653
1621 Err: 1654 Err:
1622 VP8LClear(dec); 1655 VP8LClear(dec);
1623 assert(dec->status_ != VP8_STATUS_OK); 1656 assert(dec->status_ != VP8_STATUS_OK);
1624 return 0; 1657 return 0;
1625 } 1658 }
1626 1659
1627 //------------------------------------------------------------------------------ 1660 //------------------------------------------------------------------------------
OLDNEW
« no previous file with comments | « third_party/libwebp/dec/vp8i.h ('k') | third_party/libwebp/dec/vp8li.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698