OLD | NEW |
1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // This code is licensed under the same terms as WebM: | 3 // This code is licensed under the same terms as WebM: |
4 // Software License Agreement: http://www.webmproject.org/license/software/ | 4 // Software License Agreement: http://www.webmproject.org/license/software/ |
5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ | 5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ |
6 // ----------------------------------------------------------------------------- | 6 // ----------------------------------------------------------------------------- |
7 // | 7 // |
8 // main entry for the decoder | 8 // main entry for the decoder |
9 // | 9 // |
10 // Authors: Vikas Arora (vikaas.arora@gmail.com) | 10 // Authors: Vikas Arora (vikaas.arora@gmail.com) |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 const int yoffset = dist_code >> 4; | 142 const int yoffset = dist_code >> 4; |
143 const int xoffset = 8 - (dist_code & 0xf); | 143 const int xoffset = 8 - (dist_code & 0xf); |
144 const int dist = yoffset * xsize + xoffset; | 144 const int dist = yoffset * xsize + xoffset; |
145 return (dist >= 1) ? dist : 1; | 145 return (dist >= 1) ? dist : 1; |
146 } | 146 } |
147 } | 147 } |
148 | 148 |
149 //------------------------------------------------------------------------------ | 149 //------------------------------------------------------------------------------ |
150 // Decodes the next Huffman code from bit-stream. | 150 // Decodes the next Huffman code from bit-stream. |
151 // FillBitWindow(br) needs to be called at minimum every second call | 151 // FillBitWindow(br) needs to be called at minimum every second call |
152 // to ReadSymbolUnsafe. | 152 // to ReadSymbol, in order to pre-fetch enough bits. |
153 static int ReadSymbolUnsafe(const HuffmanTree* tree, VP8LBitReader* const br) { | 153 static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree, |
| 154 VP8LBitReader* const br) { |
154 const HuffmanTreeNode* node = tree->root_; | 155 const HuffmanTreeNode* node = tree->root_; |
| 156 int num_bits = 0; |
| 157 uint32_t bits = VP8LPrefetchBits(br); |
155 assert(node != NULL); | 158 assert(node != NULL); |
156 while (!HuffmanTreeNodeIsLeaf(node)) { | 159 while (!HuffmanTreeNodeIsLeaf(node)) { |
157 node = HuffmanTreeNextNode(node, VP8LReadOneBitUnsafe(br)); | 160 node = HuffmanTreeNextNode(node, bits & 1); |
| 161 bits >>= 1; |
| 162 ++num_bits; |
158 } | 163 } |
| 164 VP8LDiscardBits(br, num_bits); |
159 return node->symbol_; | 165 return node->symbol_; |
160 } | 166 } |
161 | 167 |
162 static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree, | |
163 VP8LBitReader* const br) { | |
164 const int read_safe = (br->pos_ + 8 > br->len_); | |
165 if (!read_safe) { | |
166 return ReadSymbolUnsafe(tree, br); | |
167 } else { | |
168 const HuffmanTreeNode* node = tree->root_; | |
169 assert(node != NULL); | |
170 while (!HuffmanTreeNodeIsLeaf(node)) { | |
171 node = HuffmanTreeNextNode(node, VP8LReadOneBit(br)); | |
172 } | |
173 return node->symbol_; | |
174 } | |
175 } | |
176 | |
177 static int ReadHuffmanCodeLengths( | 168 static int ReadHuffmanCodeLengths( |
178 VP8LDecoder* const dec, const int* const code_length_code_lengths, | 169 VP8LDecoder* const dec, const int* const code_length_code_lengths, |
179 int num_symbols, int* const code_lengths) { | 170 int num_symbols, int* const code_lengths) { |
180 int ok = 0; | 171 int ok = 0; |
181 VP8LBitReader* const br = &dec->br_; | 172 VP8LBitReader* const br = &dec->br_; |
182 int symbol; | 173 int symbol; |
183 int max_symbol; | 174 int max_symbol; |
184 int prev_code_len = DEFAULT_CODE_LENGTH; | 175 int prev_code_len = DEFAULT_CODE_LENGTH; |
185 HuffmanTree tree; | 176 HuffmanTree tree; |
186 | 177 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision); | 311 const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision); |
321 const int huffman_pixs = huffman_xsize * huffman_ysize; | 312 const int huffman_pixs = huffman_xsize * huffman_ysize; |
322 if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec, | 313 if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec, |
323 &huffman_image)) { | 314 &huffman_image)) { |
324 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | 315 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; |
325 goto Error; | 316 goto Error; |
326 } | 317 } |
327 hdr->huffman_subsample_bits_ = huffman_precision; | 318 hdr->huffman_subsample_bits_ = huffman_precision; |
328 for (i = 0; i < huffman_pixs; ++i) { | 319 for (i = 0; i < huffman_pixs; ++i) { |
329 // The huffman data is stored in red and green bytes. | 320 // The huffman data is stored in red and green bytes. |
330 const int index = (huffman_image[i] >> 8) & 0xffff; | 321 const int group = (huffman_image[i] >> 8) & 0xffff; |
331 huffman_image[i] = index; | 322 huffman_image[i] = group; |
332 if (index >= num_htree_groups) { | 323 if (group >= num_htree_groups) { |
333 num_htree_groups = index + 1; | 324 num_htree_groups = group + 1; |
334 } | 325 } |
335 } | 326 } |
336 } | 327 } |
337 | 328 |
338 if (br->error_) goto Error; | 329 if (br->error_) goto Error; |
339 | 330 |
340 assert(num_htree_groups <= 0x10000); | 331 assert(num_htree_groups <= 0x10000); |
341 htree_groups = | 332 htree_groups = |
342 (HTreeGroup*)WebPSafeCalloc((uint64_t)num_htree_groups, | 333 (HTreeGroup*)WebPSafeCalloc((uint64_t)num_htree_groups, |
343 sizeof(*htree_groups)); | 334 sizeof(*htree_groups)); |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 hdr->huffman_subsample_bits_, x, y); | 599 hdr->huffman_subsample_bits_, x, y); |
609 assert(meta_index < hdr->num_htree_groups_); | 600 assert(meta_index < hdr->num_htree_groups_); |
610 return hdr->htree_groups_ + meta_index; | 601 return hdr->htree_groups_ + meta_index; |
611 } | 602 } |
612 | 603 |
613 //------------------------------------------------------------------------------ | 604 //------------------------------------------------------------------------------ |
614 // Main loop, with custom row-processing function | 605 // Main loop, with custom row-processing function |
615 | 606 |
616 typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row); | 607 typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row); |
617 | 608 |
618 static void ApplyTransforms(VP8LDecoder* const dec, int num_rows, | 609 static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows, |
619 const uint32_t* const rows) { | 610 const uint32_t* const rows) { |
620 int n = dec->next_transform_; | 611 int n = dec->next_transform_; |
621 const int cache_pixs = dec->width_ * num_rows; | 612 const int cache_pixs = dec->width_ * num_rows; |
622 uint32_t* rows_data = dec->argb_cache_; | |
623 const int start_row = dec->last_row_; | 613 const int start_row = dec->last_row_; |
624 const int end_row = start_row + num_rows; | 614 const int end_row = start_row + num_rows; |
| 615 const uint32_t* rows_in = rows; |
| 616 uint32_t* const rows_out = dec->argb_cache_; |
625 | 617 |
626 // Inverse transforms. | 618 // Inverse transforms. |
627 // TODO: most transforms only need to operate on the cropped region only. | 619 // TODO: most transforms only need to operate on the cropped region only. |
628 memcpy(rows_data, rows, cache_pixs * sizeof(*rows_data)); | 620 memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out)); |
629 while (n-- > 0) { | 621 while (n-- > 0) { |
630 VP8LTransform* const transform = &dec->transforms_[n]; | 622 VP8LTransform* const transform = &dec->transforms_[n]; |
631 VP8LInverseTransform(transform, start_row, end_row, rows, rows_data); | 623 VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out); |
| 624 rows_in = rows_out; |
632 } | 625 } |
633 } | 626 } |
634 | 627 |
635 // Processes (transforms, scales & color-converts) the rows decoded after the | 628 // Processes (transforms, scales & color-converts) the rows decoded after the |
636 // last call. | 629 // last call. |
637 static void ProcessRows(VP8LDecoder* const dec, int row) { | 630 static void ProcessRows(VP8LDecoder* const dec, int row) { |
638 const uint32_t* const rows = dec->argb_ + dec->width_ * dec->last_row_; | 631 const uint32_t* const rows = dec->argb_ + dec->width_ * dec->last_row_; |
639 const int num_rows = row - dec->last_row_; | 632 const int num_rows = row - dec->last_row_; |
640 | 633 |
641 if (num_rows <= 0) return; // Nothing to be done. | 634 if (num_rows <= 0) return; // Nothing to be done. |
642 ApplyTransforms(dec, num_rows, rows); | 635 ApplyInverseTransforms(dec, num_rows, rows); |
643 | 636 |
644 // Emit output. | 637 // Emit output. |
645 { | 638 { |
646 VP8Io* const io = dec->io_; | 639 VP8Io* const io = dec->io_; |
647 const uint32_t* rows_data = dec->argb_cache_; | 640 const uint32_t* rows_data = dec->argb_cache_; |
648 if (!SetCropWindow(io, dec->last_row_, row, &rows_data, io->width)) { | 641 if (!SetCropWindow(io, dec->last_row_, row, &rows_data, io->width)) { |
649 // Nothing to output (this time). | 642 // Nothing to output (this time). |
650 } else { | 643 } else { |
651 const WebPDecBuffer* const output = dec->output_; | 644 const WebPDecBuffer* const output = dec->output_; |
652 const int in_stride = io->width * sizeof(*rows_data); | 645 const int in_stride = io->width * sizeof(*rows_data); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 } | 783 } |
791 | 784 |
792 // ----------------------------------------------------------------------------- | 785 // ----------------------------------------------------------------------------- |
793 // VP8LTransform | 786 // VP8LTransform |
794 | 787 |
795 static void ClearTransform(VP8LTransform* const transform) { | 788 static void ClearTransform(VP8LTransform* const transform) { |
796 free(transform->data_); | 789 free(transform->data_); |
797 transform->data_ = NULL; | 790 transform->data_ = NULL; |
798 } | 791 } |
799 | 792 |
800 static void ApplyInverseTransforms(VP8LDecoder* const dec, int start_idx, | |
801 uint32_t* const decoded_data) { | |
802 int n = dec->next_transform_; | |
803 assert(start_idx >= 0); | |
804 while (n-- > start_idx) { | |
805 VP8LTransform* const transform = &dec->transforms_[n]; | |
806 VP8LInverseTransform(transform, 0, transform->ysize_, | |
807 decoded_data, decoded_data); | |
808 ClearTransform(transform); | |
809 } | |
810 dec->next_transform_ = start_idx; | |
811 } | |
812 | |
813 // For security reason, we need to remap the color map to span | 793 // For security reason, we need to remap the color map to span |
814 // the total possible bundled values, and not just the num_colors. | 794 // the total possible bundled values, and not just the num_colors. |
815 static int ExpandColorMap(int num_colors, VP8LTransform* const transform) { | 795 static int ExpandColorMap(int num_colors, VP8LTransform* const transform) { |
816 int i; | 796 int i; |
817 const int final_num_colors = 1 << (8 >> transform->bits_); | 797 const int final_num_colors = 1 << (8 >> transform->bits_); |
818 uint32_t* const new_color_map = | 798 uint32_t* const new_color_map = |
819 (uint32_t*)WebPSafeMalloc((uint64_t)final_num_colors, | 799 (uint32_t*)WebPSafeMalloc((uint64_t)final_num_colors, |
820 sizeof(*new_color_map)); | 800 sizeof(*new_color_map)); |
821 if (new_color_map == NULL) { | 801 if (new_color_map == NULL) { |
822 return 0; | 802 return 0; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 static int DecodeImageStream(int xsize, int ysize, | 937 static int DecodeImageStream(int xsize, int ysize, |
958 int is_level0, | 938 int is_level0, |
959 VP8LDecoder* const dec, | 939 VP8LDecoder* const dec, |
960 uint32_t** const decoded_data) { | 940 uint32_t** const decoded_data) { |
961 int ok = 1; | 941 int ok = 1; |
962 int transform_xsize = xsize; | 942 int transform_xsize = xsize; |
963 int transform_ysize = ysize; | 943 int transform_ysize = ysize; |
964 VP8LBitReader* const br = &dec->br_; | 944 VP8LBitReader* const br = &dec->br_; |
965 VP8LMetadata* const hdr = &dec->hdr_; | 945 VP8LMetadata* const hdr = &dec->hdr_; |
966 uint32_t* data = NULL; | 946 uint32_t* data = NULL; |
967 const int transform_start_idx = dec->next_transform_; | |
968 int color_cache_bits = 0; | 947 int color_cache_bits = 0; |
969 | 948 |
970 // Read the transforms (may recurse). | 949 // Read the transforms (may recurse). |
971 if (is_level0) { | 950 if (is_level0) { |
972 while (ok && VP8LReadBits(br, 1)) { | 951 while (ok && VP8LReadBits(br, 1)) { |
973 ok = ReadTransform(&transform_xsize, &transform_ysize, dec); | 952 ok = ReadTransform(&transform_xsize, &transform_ysize, dec); |
974 } | 953 } |
975 } | 954 } |
976 | 955 |
977 // Color cache | 956 // Color cache |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 dec->status_ = VP8_STATUS_OUT_OF_MEMORY; | 996 dec->status_ = VP8_STATUS_OUT_OF_MEMORY; |
1018 ok = 0; | 997 ok = 0; |
1019 goto End; | 998 goto End; |
1020 } | 999 } |
1021 } | 1000 } |
1022 | 1001 |
1023 // Use the Huffman trees to decode the LZ77 encoded data. | 1002 // Use the Huffman trees to decode the LZ77 encoded data. |
1024 ok = DecodeImageData(dec, data, transform_xsize, transform_ysize, NULL); | 1003 ok = DecodeImageData(dec, data, transform_xsize, transform_ysize, NULL); |
1025 ok = ok && !br->error_; | 1004 ok = ok && !br->error_; |
1026 | 1005 |
1027 // Apply transforms on the decoded data. | |
1028 if (ok) ApplyInverseTransforms(dec, transform_start_idx, data); | |
1029 | |
1030 End: | 1006 End: |
1031 | 1007 |
1032 if (!ok) { | 1008 if (!ok) { |
1033 free(data); | 1009 free(data); |
1034 ClearMetadata(hdr); | 1010 ClearMetadata(hdr); |
1035 // If not enough data (br.eos_) resulted in BIT_STREAM_ERROR, update the | 1011 // If not enough data (br.eos_) resulted in BIT_STREAM_ERROR, update the |
1036 // status appropriately. | 1012 // status appropriately. |
1037 if (dec->status_ == VP8_STATUS_BITSTREAM_ERROR && dec->br_.eos_) { | 1013 if (dec->status_ == VP8_STATUS_BITSTREAM_ERROR && dec->br_.eos_) { |
1038 dec->status_ = VP8_STATUS_SUSPENDED; | 1014 dec->status_ = VP8_STATUS_SUSPENDED; |
1039 } | 1015 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 } | 1052 } |
1077 | 1053 |
1078 //------------------------------------------------------------------------------ | 1054 //------------------------------------------------------------------------------ |
1079 // Special row-processing that only stores the alpha data. | 1055 // Special row-processing that only stores the alpha data. |
1080 | 1056 |
1081 static void ExtractAlphaRows(VP8LDecoder* const dec, int row) { | 1057 static void ExtractAlphaRows(VP8LDecoder* const dec, int row) { |
1082 const int num_rows = row - dec->last_row_; | 1058 const int num_rows = row - dec->last_row_; |
1083 const uint32_t* const in = dec->argb_ + dec->width_ * dec->last_row_; | 1059 const uint32_t* const in = dec->argb_ + dec->width_ * dec->last_row_; |
1084 | 1060 |
1085 if (num_rows <= 0) return; // Nothing to be done. | 1061 if (num_rows <= 0) return; // Nothing to be done. |
1086 ApplyTransforms(dec, num_rows, in); | 1062 ApplyInverseTransforms(dec, num_rows, in); |
1087 | 1063 |
1088 // Extract alpha (which is stored in the green plane). | 1064 // Extract alpha (which is stored in the green plane). |
1089 { | 1065 { |
1090 const int width = dec->io_->width; // the final width (!= dec->width_) | 1066 const int width = dec->io_->width; // the final width (!= dec->width_) |
1091 const int cache_pixs = width * num_rows; | 1067 const int cache_pixs = width * num_rows; |
1092 uint8_t* const dst = (uint8_t*)dec->io_->opaque + width * dec->last_row_; | 1068 uint8_t* const dst = (uint8_t*)dec->io_->opaque + width * dec->last_row_; |
1093 const uint32_t* const src = dec->argb_cache_; | 1069 const uint32_t* const src = dec->argb_cache_; |
1094 int i; | 1070 int i; |
1095 for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff; | 1071 for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff; |
1096 } | 1072 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 VP8LClear(dec); | 1182 VP8LClear(dec); |
1207 assert(dec->status_ != VP8_STATUS_OK); | 1183 assert(dec->status_ != VP8_STATUS_OK); |
1208 return 0; | 1184 return 0; |
1209 } | 1185 } |
1210 | 1186 |
1211 //------------------------------------------------------------------------------ | 1187 //------------------------------------------------------------------------------ |
1212 | 1188 |
1213 #if defined(__cplusplus) || defined(c_plusplus) | 1189 #if defined(__cplusplus) || defined(c_plusplus) |
1214 } // extern "C" | 1190 } // extern "C" |
1215 #endif | 1191 #endif |
OLD | NEW |