OLD | NEW |
1 // Copyright 2014 Google Inc. All Rights Reserved. | 1 // Copyright 2014 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 // | 14 // |
15 // Library for converting WOFF2 format font files to their TTF versions. | 15 // Library for converting WOFF2 format font files to their TTF versions. |
16 | 16 |
17 #include "./woff2_dec.h" | 17 #include "./woff2_dec.h" |
18 | 18 |
19 #include <stdlib.h> | 19 #include <stdlib.h> |
20 #include <algorithm> | 20 #include <algorithm> |
21 #include <brotli/decode.h> | |
22 #include <complex> | 21 #include <complex> |
23 #include <cstring> | 22 #include <cstring> |
24 #include <limits> | 23 #include <limits> |
25 #include <string> | 24 #include <string> |
26 #include <vector> | 25 #include <vector> |
27 #include <map> | 26 #include <map> |
28 #include <memory> | 27 #include <memory> |
29 #include <utility> | 28 #include <utility> |
30 | 29 |
| 30 #include "./brotli/decode.h" |
31 #include "./buffer.h" | 31 #include "./buffer.h" |
32 #include "./port.h" | 32 #include "./port.h" |
33 #include "./round.h" | 33 #include "./round.h" |
34 #include "./store_bytes.h" | 34 #include "./store_bytes.h" |
35 #include "./table_tags.h" | 35 #include "./table_tags.h" |
36 #include "./variable_length.h" | 36 #include "./variable_length.h" |
37 #include "./woff2_common.h" | 37 #include "./woff2_common.h" |
38 | 38 |
39 namespace woff2 { | 39 namespace woff2 { |
40 | 40 |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 return FONT_COMPRESSION_FAILURE(); | 674 return FONT_COMPRESSION_FAILURE(); |
675 } | 675 } |
676 | 676 |
677 assert(x_mins.size() == num_glyphs); | 677 assert(x_mins.size() == num_glyphs); |
678 | 678 |
679 // num_glyphs 0 is OK if there is no 'glyf' but cannot then xform 'hmtx'. | 679 // num_glyphs 0 is OK if there is no 'glyf' but cannot then xform 'hmtx'. |
680 if (PREDICT_FALSE(num_hmetrics > num_glyphs)) { | 680 if (PREDICT_FALSE(num_hmetrics > num_glyphs)) { |
681 return FONT_COMPRESSION_FAILURE(); | 681 return FONT_COMPRESSION_FAILURE(); |
682 } | 682 } |
683 | 683 |
| 684 // https://www.microsoft.com/typography/otspec/hmtx.htm |
| 685 // "...only one entry need be in the array, but that entry is required." |
| 686 if (PREDICT_FALSE(num_hmetrics < 1)) { |
| 687 return FONT_COMPRESSION_FAILURE(); |
| 688 } |
| 689 |
684 for (uint16_t i = 0; i < num_hmetrics; i++) { | 690 for (uint16_t i = 0; i < num_hmetrics; i++) { |
685 uint16_t advance_width; | 691 uint16_t advance_width; |
686 if (PREDICT_FALSE(!hmtx_buff_in.ReadU16(&advance_width))) { | 692 if (PREDICT_FALSE(!hmtx_buff_in.ReadU16(&advance_width))) { |
687 return FONT_COMPRESSION_FAILURE(); | 693 return FONT_COMPRESSION_FAILURE(); |
688 } | 694 } |
689 advance_widths.push_back(advance_width); | 695 advance_widths.push_back(advance_width); |
690 } | 696 } |
691 | 697 |
692 for (uint16_t i = 0; i < num_hmetrics; i++) { | 698 for (uint16_t i = 0; i < num_hmetrics; i++) { |
693 int16_t lsb; | 699 int16_t lsb; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 | 738 |
733 return true; | 739 return true; |
734 } | 740 } |
735 | 741 |
736 bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size, | 742 bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size, |
737 const uint8_t* src_buf, size_t src_size) { | 743 const uint8_t* src_buf, size_t src_size) { |
738 size_t uncompressed_size = dst_size; | 744 size_t uncompressed_size = dst_size; |
739 BrotliDecoderResult result = BrotliDecoderDecompress( | 745 BrotliDecoderResult result = BrotliDecoderDecompress( |
740 src_size, src_buf, &uncompressed_size, dst_buf); | 746 src_size, src_buf, &uncompressed_size, dst_buf); |
741 if (PREDICT_FALSE(result != BROTLI_DECODER_RESULT_SUCCESS || | 747 if (PREDICT_FALSE(result != BROTLI_DECODER_RESULT_SUCCESS || |
742 uncompressed_size != dst_size)) { | 748 uncompressed_size != dst_size)) { |
743 return FONT_COMPRESSION_FAILURE(); | 749 return FONT_COMPRESSION_FAILURE(); |
744 } | 750 } |
745 return true; | 751 return true; |
746 } | 752 } |
747 | 753 |
748 bool ReadTableDirectory(Buffer* file, std::vector<Table>* tables, | 754 bool ReadTableDirectory(Buffer* file, std::vector<Table>* tables, |
749 size_t num_tables) { | 755 size_t num_tables) { |
750 uint32_t src_offset = 0; | 756 uint32_t src_offset = 0; |
751 for (size_t i = 0; i < num_tables; ++i) { | 757 for (size_t i = 0; i < num_tables; ++i) { |
752 Table* table = &(*tables)[i]; | 758 Table* table = &(*tables)[i]; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 if (table.tag == kHeadTableTag) { | 917 if (table.tag == kHeadTableTag) { |
912 if (PREDICT_FALSE(table.src_length < 12)) { | 918 if (PREDICT_FALSE(table.src_length < 12)) { |
913 return FONT_COMPRESSION_FAILURE(); | 919 return FONT_COMPRESSION_FAILURE(); |
914 } | 920 } |
915 // checkSumAdjustment = 0 | 921 // checkSumAdjustment = 0 |
916 StoreU32(transformed_buf + table.src_offset, 8, 0); | 922 StoreU32(transformed_buf + table.src_offset, 8, 0); |
917 } | 923 } |
918 table.dst_offset = dest_offset; | 924 table.dst_offset = dest_offset; |
919 checksum = ComputeULongSum(transformed_buf + table.src_offset, | 925 checksum = ComputeULongSum(transformed_buf + table.src_offset, |
920 table.src_length); | 926 table.src_length); |
921 out->Write(transformed_buf + table.src_offset, table.src_length); | 927 if (PREDICT_FALSE(!out->Write(transformed_buf + table.src_offset, |
| 928 table.src_length))) { |
| 929 return FONT_COMPRESSION_FAILURE(); |
| 930 } |
922 } else { | 931 } else { |
923 if (table.tag == kGlyfTableTag) { | 932 if (table.tag == kGlyfTableTag) { |
924 table.dst_offset = dest_offset; | 933 table.dst_offset = dest_offset; |
925 | 934 |
926 Table* loca_table = FindTable(&tables, kLocaTableTag); | 935 Table* loca_table = FindTable(&tables, kLocaTableTag); |
927 if (PREDICT_FALSE(!ReconstructGlyf(transformed_buf + table.src_offset, | 936 if (PREDICT_FALSE(!ReconstructGlyf(transformed_buf + table.src_offset, |
928 &table, &checksum, loca_table, &loca_checksum, info, out))) { | 937 &table, &checksum, loca_table, &loca_checksum, info, out))) { |
929 return FONT_COMPRESSION_FAILURE(); | 938 return FONT_COMPRESSION_FAILURE(); |
930 } | 939 } |
931 } else if (table.tag == kLocaTableTag) { | 940 } else if (table.tag == kLocaTableTag) { |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 hdr.uncompressed_size, | 1310 hdr.uncompressed_size, |
1302 &metadata, &hdr, i, out))) { | 1311 &metadata, &hdr, i, out))) { |
1303 return FONT_COMPRESSION_FAILURE(); | 1312 return FONT_COMPRESSION_FAILURE(); |
1304 } | 1313 } |
1305 } | 1314 } |
1306 | 1315 |
1307 return true; | 1316 return true; |
1308 } | 1317 } |
1309 | 1318 |
1310 } // namespace woff2 | 1319 } // namespace woff2 |
OLD | NEW |