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

Side by Side Diff: third_party/ots/src/woff2.cc

Issue 1252363005: Update OTS to revision a7a3b94 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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/ots/src/woff2.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This is the implementation of decompression of the proposed WOFF Ultra 5 // This is the implementation of decompression of the proposed WOFF Ultra
6 // Condensed file format. 6 // Condensed file format.
7 7
8 #include <cassert> 8 #include <cassert>
9 #include <cstdlib> 9 #include <cstdlib>
10 #include <vector> 10 #include <vector>
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 } 175 }
176 } 176 }
177 177
178 bool ReadBase128(ots::Buffer* buf, uint32_t* value) { 178 bool ReadBase128(ots::Buffer* buf, uint32_t* value) {
179 uint32_t result = 0; 179 uint32_t result = 0;
180 for (size_t i = 0; i < 5; ++i) { 180 for (size_t i = 0; i < 5; ++i) {
181 uint8_t code = 0; 181 uint8_t code = 0;
182 if (!buf->ReadU8(&code)) { 182 if (!buf->ReadU8(&code)) {
183 return OTS_FAILURE(); 183 return OTS_FAILURE();
184 } 184 }
185 if (i == 0 && code == 0x80) {
186 return OTS_FAILURE();
187 }
185 // If any of the top seven bits are set then we're about to overflow. 188 // If any of the top seven bits are set then we're about to overflow.
186 if (result & 0xfe000000U) { 189 if (result & 0xfe000000U) {
187 return OTS_FAILURE(); 190 return OTS_FAILURE();
188 } 191 }
189 result = (result << 7) | (code & 0x7f); 192 result = (result << 7) | (code & 0x7f);
190 if ((code & 0x80) == 0) { 193 if ((code & 0x80) == 0) {
191 *value = result; 194 *value = result;
192 return true; 195 return true;
193 } 196 }
194 } 197 }
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 if (index_format) { 506 if (index_format) {
504 offset = StoreU32(dst, offset, value); 507 offset = StoreU32(dst, offset, value);
505 } else { 508 } else {
506 offset = StoreU16(dst, offset, static_cast<uint16_t>(value >> 1)); 509 offset = StoreU16(dst, offset, static_cast<uint16_t>(value >> 1));
507 } 510 }
508 } 511 }
509 return true; 512 return true;
510 } 513 }
511 514
512 // Reconstruct entire glyf table based on transformed original 515 // Reconstruct entire glyf table based on transformed original
513 bool ReconstructGlyf(ots::OpenTypeFile* file, 516 bool ReconstructGlyf(ots::Font *font,
514 const uint8_t* data, size_t data_size, 517 const uint8_t* data, size_t data_size,
515 uint8_t* dst, size_t dst_size, 518 uint8_t* dst, size_t dst_size,
516 uint8_t* loca_buf, size_t loca_size) { 519 uint8_t* loca_buf, size_t loca_size) {
517 static const int kNumSubStreams = 7; 520 static const int kNumSubStreams = 7;
518 ots::Buffer buffer(data, data_size); 521 ots::Buffer buffer(data, data_size);
519 uint32_t version; 522 uint32_t version;
520 std::vector<std::pair<const uint8_t*, size_t> > substreams(kNumSubStreams); 523 std::vector<std::pair<const uint8_t*, size_t> > substreams(kNumSubStreams);
521 524
522 if (!buffer.ReadU32(&version)) { 525 if (!buffer.ReadU32(&version)) {
523 return OTS_FAILURE_MSG("Failed to read 'version' of transformed 'glyf' table "); 526 return OTS_FAILURE_MSG("Failed to read 'version' of transformed 'glyf' table ");
(...skipping 29 matching lines...) Expand all
553 ots::Buffer composite_stream(substreams.at(4).first, substreams.at(4).second); 556 ots::Buffer composite_stream(substreams.at(4).first, substreams.at(4).second);
554 ots::Buffer bbox_stream(substreams.at(5).first, substreams.at(5).second); 557 ots::Buffer bbox_stream(substreams.at(5).first, substreams.at(5).second);
555 ots::Buffer instruction_stream(substreams.at(6).first, 558 ots::Buffer instruction_stream(substreams.at(6).first,
556 substreams.at(6).second); 559 substreams.at(6).second);
557 560
558 std::vector<uint32_t> loca_values; 561 std::vector<uint32_t> loca_values;
559 loca_values.reserve(num_glyphs + 1); 562 loca_values.reserve(num_glyphs + 1);
560 std::vector<uint16_t> n_points_vec; 563 std::vector<uint16_t> n_points_vec;
561 std::vector<Point> points; 564 std::vector<Point> points;
562 uint32_t loca_offset = 0; 565 uint32_t loca_offset = 0;
566 const uint8_t* bbox_bitmap = bbox_stream.buffer();
563 for (unsigned int i = 0; i < num_glyphs; ++i) { 567 for (unsigned int i = 0; i < num_glyphs; ++i) {
564 size_t glyph_size = 0; 568 size_t glyph_size = 0;
565 uint16_t n_contours = 0; 569 uint16_t n_contours = 0;
566 if (!n_contour_stream.ReadU16(&n_contours)) { 570 if (!n_contour_stream.ReadU16(&n_contours)) {
567 return OTS_FAILURE_MSG("Filed to read 'numberOfContours' of glyph %d from transformed 'glyf' table", i); 571 return OTS_FAILURE_MSG("Filed to read 'numberOfContours' of glyph %d from transformed 'glyf' table", i);
568 } 572 }
569 uint8_t* glyf_dst = dst + loca_offset; 573 uint8_t* glyf_dst = dst + loca_offset;
570 size_t glyf_dst_size = dst_size - loca_offset; 574 size_t glyf_dst_size = dst_size - loca_offset;
571 if (n_contours == 0xffff) { 575 if (n_contours == 0xffff) {
572 // composite glyph 576 // composite glyph
577 if (!(bbox_bitmap[i >> 3] & (0x80 >> (i & 7)))) {
578 return OTS_FAILURE_MSG("Composite glyph %d without bbox", i);
579 }
573 bool have_instructions = false; 580 bool have_instructions = false;
574 uint16_t instruction_size = 0; 581 uint16_t instruction_size = 0;
575 if (!ProcessComposite(&composite_stream, glyf_dst, glyf_dst_size, 582 if (!ProcessComposite(&composite_stream, glyf_dst, glyf_dst_size,
576 &glyph_size, &have_instructions)) { 583 &glyph_size, &have_instructions)) {
577 return OTS_FAILURE_MSG("Filed to process composite glyph %d from transfo rmed 'glyf' table", i); 584 return OTS_FAILURE_MSG("Filed to process composite glyph %d from transfo rmed 'glyf' table", i);
578 } 585 }
579 if (have_instructions) { 586 if (have_instructions) {
580 if (!Read255UShort(&glyph_stream, &instruction_size)) { 587 if (!Read255UShort(&glyph_stream, &instruction_size)) {
581 return OTS_FAILURE_MSG("Failed to read 'instructionLength' of glyph %d from transformed 'glyf' table", i); 588 return OTS_FAILURE_MSG("Failed to read 'instructionLength' of glyph %d from transformed 'glyf' table", i);
582 } 589 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 const Table* FindTable(const std::vector<Table>& tables, uint32_t tag) { 697 const Table* FindTable(const std::vector<Table>& tables, uint32_t tag) {
691 size_t n_tables = tables.size(); 698 size_t n_tables = tables.size();
692 for (size_t i = 0; i < n_tables; ++i) { 699 for (size_t i = 0; i < n_tables; ++i) {
693 if (tables.at(i).tag == tag) { 700 if (tables.at(i).tag == tag) {
694 return &tables.at(i); 701 return &tables.at(i);
695 } 702 }
696 } 703 }
697 return NULL; 704 return NULL;
698 } 705 }
699 706
700 bool ReconstructTransformed(ots::OpenTypeFile* file, 707 bool ReconstructTransformed(ots::Font *font,
701 const std::vector<Table>& tables, uint32_t tag, 708 const std::vector<Table>& tables, uint32_t tag,
702 const uint8_t* transformed_buf, size_t transformed_size, 709 const uint8_t* transformed_buf, size_t transformed_size,
703 uint8_t* dst, size_t dst_length) { 710 uint8_t* dst, size_t dst_length) {
704 if (tag == OTS_TAG('g','l','y','f')) { 711 if (tag == OTS_TAG('g','l','y','f')) {
705 const Table* glyf_table = FindTable(tables, tag); 712 const Table* glyf_table = FindTable(tables, tag);
706 const Table* loca_table = FindTable(tables, OTS_TAG('l','o','c','a')); 713 const Table* loca_table = FindTable(tables, OTS_TAG('l','o','c','a'));
707 if (glyf_table == NULL || loca_table == NULL) { 714 if (glyf_table == NULL || loca_table == NULL) {
708 return OTS_FAILURE(); 715 return OTS_FAILURE();
709 } 716 }
710 if (static_cast<uint64_t>(glyf_table->dst_offset) + glyf_table->dst_length > 717 if (static_cast<uint64_t>(glyf_table->dst_offset) + glyf_table->dst_length >
711 dst_length) { 718 dst_length) {
712 return OTS_FAILURE(); 719 return OTS_FAILURE();
713 } 720 }
714 if (static_cast<uint64_t>(loca_table->dst_offset) + loca_table->dst_length > 721 if (static_cast<uint64_t>(loca_table->dst_offset) + loca_table->dst_length >
715 dst_length) { 722 dst_length) {
716 return OTS_FAILURE(); 723 return OTS_FAILURE();
717 } 724 }
718 return ReconstructGlyf(file, transformed_buf, transformed_size, 725 return ReconstructGlyf(font, transformed_buf, transformed_size,
719 dst + glyf_table->dst_offset, glyf_table->dst_length, 726 dst + glyf_table->dst_offset, glyf_table->dst_length,
720 dst + loca_table->dst_offset, loca_table->dst_length); 727 dst + loca_table->dst_offset, loca_table->dst_length);
721 } else if (tag == OTS_TAG('l','o','c','a')) { 728 } else if (tag == OTS_TAG('l','o','c','a')) {
722 // processing was already done by glyf table, but validate 729 // processing was already done by glyf table, but validate
723 if (!FindTable(tables, OTS_TAG('g','l','y','f'))) { 730 if (!FindTable(tables, OTS_TAG('g','l','y','f'))) {
724 return OTS_FAILURE(); 731 return OTS_FAILURE();
725 } 732 }
726 } else { 733 } else {
727 // transform for the tag is not known 734 // transform for the tag is not known
728 return OTS_FAILURE(); 735 return OTS_FAILURE();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 StoreU32(dst, kSfntHeaderSize + i * kSfntEntrySize + 4, checksum); 768 StoreU32(dst, kSfntHeaderSize + i * kSfntEntrySize + 4, checksum);
762 file_checksum += checksum; // The addition is mod 2^32 769 file_checksum += checksum; // The addition is mod 2^32
763 } 770 }
764 file_checksum += ComputeChecksum(dst, 771 file_checksum += ComputeChecksum(dst,
765 kSfntHeaderSize + kSfntEntrySize * n_tables); 772 kSfntHeaderSize + kSfntEntrySize * n_tables);
766 uint32_t checksum_adjustment = 0xb1b0afba - file_checksum; 773 uint32_t checksum_adjustment = 0xb1b0afba - file_checksum;
767 StoreU32(dst, adjustment_offset, checksum_adjustment); 774 StoreU32(dst, adjustment_offset, checksum_adjustment);
768 return true; 775 return true;
769 } 776 }
770 777
771 bool ReadTableDirectory(ots::OpenTypeFile* file, 778 bool ReadTableDirectory(ots::Font *font,
772 ots::Buffer* buffer, std::vector<Table>* tables, 779 ots::Buffer* buffer, std::vector<Table>* tables,
773 size_t num_tables) { 780 size_t num_tables) {
774 for (size_t i = 0; i < num_tables; ++i) { 781 for (size_t i = 0; i < num_tables; ++i) {
775 Table* table = &tables->at(i); 782 Table* table = &tables->at(i);
776 uint8_t flag_byte; 783 uint8_t flag_byte;
777 if (!buffer->ReadU8(&flag_byte)) { 784 if (!buffer->ReadU8(&flag_byte)) {
778 return OTS_FAILURE_MSG("Failed to read the flags of table directory entry %d", i); 785 return OTS_FAILURE_MSG("Failed to read the flags of table directory entry %d", i);
779 } 786 }
780 uint32_t tag; 787 uint32_t tag;
781 if ((flag_byte & 0x3f) == 0x3f) { 788 if ((flag_byte & 0x3f) == 0x3f) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 ots::Buffer file(data, length); 837 ots::Buffer file(data, length);
831 uint32_t total_length; 838 uint32_t total_length;
832 839
833 if (!file.Skip(16) || 840 if (!file.Skip(16) ||
834 !file.ReadU32(&total_length)) { 841 !file.ReadU32(&total_length)) {
835 return 0; 842 return 0;
836 } 843 }
837 return total_length; 844 return total_length;
838 } 845 }
839 846
840 bool ConvertWOFF2ToSFNT(ots::OpenTypeFile* file, 847 bool ConvertWOFF2ToSFNT(ots::Font *font,
841 uint8_t* result, size_t result_length, 848 uint8_t* result, size_t result_length,
842 const uint8_t* data, size_t length) { 849 const uint8_t* data, size_t length) {
843 static const uint32_t kWoff2Signature = 0x774f4632; // "wOF2" 850 static const uint32_t kWoff2Signature = 0x774f4632; // "wOF2"
844 ots::Buffer buffer(data, length); 851 ots::Buffer buffer(data, length);
845 852
846 uint32_t signature; 853 uint32_t signature;
847 uint32_t flavor = 0; 854 uint32_t flavor = 0;
848 if (!buffer.ReadU32(&signature) || signature != kWoff2Signature || 855 if (!buffer.ReadU32(&signature) || signature != kWoff2Signature ||
849 !buffer.ReadU32(&flavor)) { 856 !buffer.ReadU32(&flavor)) {
850 return OTS_FAILURE_MSG("Failed to read 'signature' or 'flavor', or not WOFF2 signature"); 857 return OTS_FAILURE_MSG("Failed to read 'signature' or 'flavor', or not WOFF2 signature");
851 } 858 }
852 859
853 if (!IsValidVersionTag(ntohl(flavor))) { 860 if (!IsValidVersionTag(flavor)) {
854 return OTS_FAILURE_MSG("Invalid 'flavor'"); 861 return OTS_FAILURE_MSG("Invalid 'flavor'");
855 } 862 }
856 863
857 uint32_t reported_length; 864 uint32_t reported_length;
858 if (!buffer.ReadU32(&reported_length) || length != reported_length) { 865 if (!buffer.ReadU32(&reported_length) || length != reported_length) {
859 return OTS_FAILURE_MSG("Failed to read 'length' or it does not match the act ual file size"); 866 return OTS_FAILURE_MSG("Failed to read 'length' or it does not match the act ual file size");
860 } 867 }
861 uint16_t num_tables; 868 uint16_t num_tables;
862 if (!buffer.ReadU16(&num_tables) || !num_tables) { 869 if (!buffer.ReadU16(&num_tables) || !num_tables) {
863 return OTS_FAILURE_MSG("Failed to read 'numTables'"); 870 return OTS_FAILURE_MSG("Failed to read 'numTables'");
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 !buffer.ReadU32(&priv_length)) { 916 !buffer.ReadU32(&priv_length)) {
910 return OTS_FAILURE_MSG("Failed to read header private block fields"); 917 return OTS_FAILURE_MSG("Failed to read header private block fields");
911 } 918 }
912 if (priv_offset) { 919 if (priv_offset) {
913 if (priv_offset >= length || length - priv_offset < priv_length) { 920 if (priv_offset >= length || length - priv_offset < priv_length) {
914 return OTS_FAILURE_MSG("Invalid private block offset or length"); 921 return OTS_FAILURE_MSG("Invalid private block offset or length");
915 } 922 }
916 } 923 }
917 924
918 std::vector<Table> tables(num_tables); 925 std::vector<Table> tables(num_tables);
919 if (!ReadTableDirectory(file, &buffer, &tables, num_tables)) { 926 if (!ReadTableDirectory(font, &buffer, &tables, num_tables)) {
920 return OTS_FAILURE_MSG("Failed to read table directory"); 927 return OTS_FAILURE_MSG("Failed to read table directory");
921 } 928 }
922 uint64_t compressed_offset = buffer.offset(); 929 uint64_t compressed_offset = buffer.offset();
923 if (compressed_offset > std::numeric_limits<uint32_t>::max()) { 930 if (compressed_offset > std::numeric_limits<uint32_t>::max()) {
924 return OTS_FAILURE(); 931 return OTS_FAILURE();
925 } 932 }
926 uint64_t dst_offset = kSfntHeaderSize + 933 uint64_t dst_offset = kSfntHeaderSize +
927 kSfntEntrySize * static_cast<uint64_t>(num_tables); 934 kSfntEntrySize * static_cast<uint64_t>(num_tables);
928 for (uint16_t i = 0; i < num_tables; ++i) { 935 for (uint16_t i = 0; i < num_tables; ++i) {
929 Table* table = &tables.at(i); 936 Table* table = &tables.at(i);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 if (transform_length != table->dst_length) { 1037 if (transform_length != table->dst_length) {
1031 return OTS_FAILURE(); 1038 return OTS_FAILURE();
1032 } 1039 }
1033 if (static_cast<uint64_t>(table->dst_offset) + transform_length > 1040 if (static_cast<uint64_t>(table->dst_offset) + transform_length >
1034 result_length) { 1041 result_length) {
1035 return OTS_FAILURE(); 1042 return OTS_FAILURE();
1036 } 1043 }
1037 std::memcpy(result + table->dst_offset, transform_buf, 1044 std::memcpy(result + table->dst_offset, transform_buf,
1038 transform_length); 1045 transform_length);
1039 } else { 1046 } else {
1040 if (!ReconstructTransformed(file, tables, table->tag, 1047 if (!ReconstructTransformed(font, tables, table->tag,
1041 transform_buf, transform_length, result, result_length)) { 1048 transform_buf, transform_length, result, result_length)) {
1042 return OTS_FAILURE_MSG("Failed to reconstruct '%c%c%c%c' table", OTS_UNT AG(table->tag)); 1049 return OTS_FAILURE_MSG("Failed to reconstruct '%c%c%c%c' table", OTS_UNT AG(table->tag));
1043 } 1050 }
1044 } 1051 }
1045 1052
1046 transform_buf += transform_length; 1053 transform_buf += transform_length;
1047 if (transform_buf > &uncompressed_buf[0] + uncompressed_buf.size()) { 1054 if (transform_buf > &uncompressed_buf[0] + uncompressed_buf.size()) {
1048 return OTS_FAILURE(); 1055 return OTS_FAILURE();
1049 } 1056 }
1050 } 1057 }
1051 1058
1052 return FixChecksums(sorted_tables, result); 1059 return FixChecksums(sorted_tables, result);
1053 } 1060 }
1054 1061
1055 } // namespace ots 1062 } // namespace ots
1056 1063
1057 #undef TABLE_NAME 1064 #undef TABLE_NAME
OLDNEW
« no previous file with comments | « third_party/ots/src/woff2.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698