yusukes@chromium.org | d257d18 | 2009-11-04 04:56:32 +0000 | [diff] [blame] | 1 | // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef OPENTYPE_SANITISER_H_ |
| 6 | #define OPENTYPE_SANITISER_H_ |
| 7 | |
agl@chromium.org | 6a0c735 | 2011-01-12 16:34:40 +0000 | [diff] [blame] | 8 | #if defined(_WIN32) |
agl@chromium.org | 98281af | 2012-02-24 18:05:29 +0000 | [diff] [blame] | 9 | #include <stdlib.h> |
yusukes@chromium.org | d257d18 | 2009-11-04 04:56:32 +0000 | [diff] [blame] | 10 | typedef signed char int8_t; |
| 11 | typedef unsigned char uint8_t; |
| 12 | typedef short int16_t; |
| 13 | typedef unsigned short uint16_t; |
| 14 | typedef int int32_t; |
| 15 | typedef unsigned int uint32_t; |
| 16 | typedef __int64 int64_t; |
| 17 | typedef unsigned __int64 uint64_t; |
agl@chromium.org | 98281af | 2012-02-24 18:05:29 +0000 | [diff] [blame] | 18 | #define ntohl(x) _byteswap_ulong (x) |
| 19 | #define ntohs(x) _byteswap_ushort (x) |
| 20 | #define htonl(x) _byteswap_ulong (x) |
| 21 | #define htons(x) _byteswap_ushort (x) |
yusukes@chromium.org | d257d18 | 2009-11-04 04:56:32 +0000 | [diff] [blame] | 22 | #else |
| 23 | #include <arpa/inet.h> |
| 24 | #include <stdint.h> |
| 25 | #endif |
| 26 | |
| 27 | #include <algorithm> // for std::min |
| 28 | #include <cassert> |
agl@chromium.org | 1890818 | 2011-06-06 13:47:33 +0000 | [diff] [blame] | 29 | #include <cstddef> |
yusukes@chromium.org | d257d18 | 2009-11-04 04:56:32 +0000 | [diff] [blame] | 30 | #include <cstring> |
| 31 | |
| 32 | namespace ots { |
| 33 | |
| 34 | // ----------------------------------------------------------------------------- |
| 35 | // This is an interface for an abstract stream class which is used for writing |
| 36 | // the serialised results out. |
| 37 | // ----------------------------------------------------------------------------- |
| 38 | class OTSStream { |
| 39 | public: |
| 40 | OTSStream() { |
| 41 | ResetChecksum(); |
| 42 | } |
| 43 | |
| 44 | virtual ~OTSStream() {} |
| 45 | |
| 46 | // This should be implemented to perform the actual write. |
| 47 | virtual bool WriteRaw(const void *data, size_t length) = 0; |
| 48 | |
| 49 | bool Write(const void *data, size_t length) { |
| 50 | if (!length) return false; |
| 51 | |
| 52 | const size_t orig_length = length; |
| 53 | size_t offset = 0; |
| 54 | if (chksum_buffer_offset_) { |
| 55 | const size_t l = |
| 56 | std::min(length, static_cast<size_t>(4) - chksum_buffer_offset_); |
| 57 | std::memcpy(chksum_buffer_ + chksum_buffer_offset_, data, l); |
| 58 | chksum_buffer_offset_ += l; |
| 59 | offset += l; |
| 60 | length -= l; |
| 61 | } |
| 62 | |
| 63 | if (chksum_buffer_offset_ == 4) { |
yusukes@chromium.org | 19a629d | 2012-01-24 07:03:12 +0000 | [diff] [blame] | 64 | uint32_t chksum; |
| 65 | std::memcpy(&chksum, chksum_buffer_, 4); |
| 66 | chksum_ += ntohl(chksum); |
yusukes@chromium.org | d257d18 | 2009-11-04 04:56:32 +0000 | [diff] [blame] | 67 | chksum_buffer_offset_ = 0; |
| 68 | } |
| 69 | |
| 70 | while (length >= 4) { |
| 71 | chksum_ += ntohl(*reinterpret_cast<const uint32_t*>( |
| 72 | reinterpret_cast<const uint8_t*>(data) + offset)); |
| 73 | length -= 4; |
| 74 | offset += 4; |
| 75 | } |
| 76 | |
| 77 | if (length) { |
| 78 | if (chksum_buffer_offset_ != 0) return false; // not reached |
| 79 | if (length > 4) return false; // not reached |
| 80 | std::memcpy(chksum_buffer_, |
| 81 | reinterpret_cast<const uint8_t*>(data) + offset, length); |
| 82 | chksum_buffer_offset_ = length; |
| 83 | } |
| 84 | |
| 85 | return WriteRaw(data, orig_length); |
| 86 | } |
| 87 | |
| 88 | virtual bool Seek(off_t position) = 0; |
| 89 | virtual off_t Tell() const = 0; |
| 90 | |
| 91 | virtual bool Pad(size_t bytes) { |
| 92 | static const uint32_t kZero = 0; |
| 93 | while (bytes >= 4) { |
| 94 | if (!WriteTag(kZero)) return false; |
| 95 | bytes -= 4; |
| 96 | } |
| 97 | while (bytes) { |
| 98 | static const uint8_t kZerob = 0; |
| 99 | if (!Write(&kZerob, 1)) return false; |
| 100 | bytes--; |
| 101 | } |
| 102 | return true; |
| 103 | } |
| 104 | |
bashi@google.com | 93aedf7 | 2010-12-24 00:29:23 +0000 | [diff] [blame] | 105 | bool WriteU8(uint8_t v) { |
| 106 | return Write(&v, sizeof(v)); |
| 107 | } |
| 108 | |
yusukes@chromium.org | d257d18 | 2009-11-04 04:56:32 +0000 | [diff] [blame] | 109 | bool WriteU16(uint16_t v) { |
| 110 | v = htons(v); |
| 111 | return Write(&v, sizeof(v)); |
| 112 | } |
| 113 | |
| 114 | bool WriteS16(int16_t v) { |
| 115 | v = htons(v); |
| 116 | return Write(&v, sizeof(v)); |
| 117 | } |
| 118 | |
bashi@google.com | 93aedf7 | 2010-12-24 00:29:23 +0000 | [diff] [blame] | 119 | bool WriteU24(uint32_t v) { |
| 120 | v = htonl(v); |
| 121 | return Write(reinterpret_cast<uint8_t*>(&v)+1, 3); |
| 122 | } |
| 123 | |
yusukes@chromium.org | d257d18 | 2009-11-04 04:56:32 +0000 | [diff] [blame] | 124 | bool WriteU32(uint32_t v) { |
| 125 | v = htonl(v); |
| 126 | return Write(&v, sizeof(v)); |
| 127 | } |
| 128 | |
| 129 | bool WriteS32(int32_t v) { |
| 130 | v = htonl(v); |
| 131 | return Write(&v, sizeof(v)); |
| 132 | } |
| 133 | |
| 134 | bool WriteR64(uint64_t v) { |
| 135 | return Write(&v, sizeof(v)); |
| 136 | } |
| 137 | |
| 138 | bool WriteTag(uint32_t v) { |
| 139 | return Write(&v, sizeof(v)); |
| 140 | } |
| 141 | |
| 142 | void ResetChecksum() { |
| 143 | chksum_ = 0; |
| 144 | chksum_buffer_offset_ = 0; |
| 145 | } |
| 146 | |
| 147 | uint32_t chksum() const { |
| 148 | assert(chksum_buffer_offset_ == 0); |
| 149 | return chksum_; |
| 150 | } |
| 151 | |
| 152 | struct ChecksumState { |
| 153 | uint32_t chksum; |
| 154 | uint8_t chksum_buffer[4]; |
| 155 | unsigned chksum_buffer_offset; |
| 156 | }; |
| 157 | |
| 158 | ChecksumState SaveChecksumState() const { |
| 159 | ChecksumState s; |
| 160 | s.chksum = chksum_; |
| 161 | s.chksum_buffer_offset = chksum_buffer_offset_; |
| 162 | std::memcpy(s.chksum_buffer, chksum_buffer_, 4); |
| 163 | |
| 164 | return s; |
| 165 | } |
| 166 | |
| 167 | void RestoreChecksum(const ChecksumState &s) { |
| 168 | assert(chksum_buffer_offset_ == 0); |
| 169 | chksum_ += s.chksum; |
| 170 | chksum_buffer_offset_ = s.chksum_buffer_offset; |
| 171 | std::memcpy(chksum_buffer_, s.chksum_buffer, 4); |
| 172 | } |
| 173 | |
| 174 | protected: |
| 175 | uint32_t chksum_; |
| 176 | uint8_t chksum_buffer_[4]; |
| 177 | unsigned chksum_buffer_offset_; |
| 178 | }; |
| 179 | |
| 180 | // ----------------------------------------------------------------------------- |
| 181 | // Process a given OpenType file and write out a sanitised version |
| 182 | // output: a pointer to an object implementing the OTSStream interface. The |
| 183 | // sanitisied output will be written to this. In the even of a failure, |
| 184 | // partial output may have been written. |
| 185 | // input: the OpenType file |
| 186 | // length: the size, in bytes, of |input| |
| 187 | // ----------------------------------------------------------------------------- |
| 188 | bool Process(OTSStream *output, const uint8_t *input, size_t length); |
| 189 | |
| 190 | // Force to disable debug output even when the library is compiled with |
| 191 | // -DOTS_DEBUG. |
| 192 | void DisableDebugOutput(); |
| 193 | |
ksakamoto@chromium.org | 74343ba | 2013-05-08 01:20:29 +0000 | [diff] [blame] | 194 | // Enable WOFF2 support(experimental). |
bashi@chromium.org | 6462c58 | 2014-06-27 06:24:49 +0000 | [diff] [blame] | 195 | // TODO(bashi): Remove WOFF2 from OTS. |
ksakamoto@chromium.org | 74343ba | 2013-05-08 01:20:29 +0000 | [diff] [blame] | 196 | void EnableWOFF2(); |
| 197 | |
bashi@chromium.org | 6462c58 | 2014-06-27 06:24:49 +0000 | [diff] [blame] | 198 | // Force to disable dropping CBDT/CBLC tables. |
| 199 | void DoNotDropColorBitmapTables(); |
| 200 | |
yusukes@chromium.org | d257d18 | 2009-11-04 04:56:32 +0000 | [diff] [blame] | 201 | } // namespace ots |
| 202 | |
| 203 | #endif // OPENTYPE_SANITISER_H_ |