blob: 495242686c015cb4fb8f6c98f5e13ec0293de98d [file] [log] [blame]
yusukes@chromium.orgd257d182009-11-04 04:56:32 +00001// 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.org6a0c7352011-01-12 16:34:40 +00008#if defined(_WIN32)
agl@chromium.org98281af2012-02-24 18:05:29 +00009#include <stdlib.h>
yusukes@chromium.orgd257d182009-11-04 04:56:32 +000010typedef signed char int8_t;
11typedef unsigned char uint8_t;
12typedef short int16_t;
13typedef unsigned short uint16_t;
14typedef int int32_t;
15typedef unsigned int uint32_t;
16typedef __int64 int64_t;
17typedef unsigned __int64 uint64_t;
agl@chromium.org98281af2012-02-24 18:05:29 +000018#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.orgd257d182009-11-04 04:56:32 +000022#else
23#include <arpa/inet.h>
24#include <stdint.h>
25#endif
26
27#include <algorithm> // for std::min
28#include <cassert>
agl@chromium.org18908182011-06-06 13:47:33 +000029#include <cstddef>
yusukes@chromium.orgd257d182009-11-04 04:56:32 +000030#include <cstring>
31
32namespace ots {
33
34// -----------------------------------------------------------------------------
35// This is an interface for an abstract stream class which is used for writing
36// the serialised results out.
37// -----------------------------------------------------------------------------
38class 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.org19a629d2012-01-24 07:03:12 +000064 uint32_t chksum;
65 std::memcpy(&chksum, chksum_buffer_, 4);
66 chksum_ += ntohl(chksum);
yusukes@chromium.orgd257d182009-11-04 04:56:32 +000067 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.com93aedf72010-12-24 00:29:23 +0000105 bool WriteU8(uint8_t v) {
106 return Write(&v, sizeof(v));
107 }
108
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000109 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.com93aedf72010-12-24 00:29:23 +0000119 bool WriteU24(uint32_t v) {
120 v = htonl(v);
121 return Write(reinterpret_cast<uint8_t*>(&v)+1, 3);
122 }
123
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000124 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// -----------------------------------------------------------------------------
188bool 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.
192void DisableDebugOutput();
193
ksakamoto@chromium.org74343ba2013-05-08 01:20:29 +0000194// Enable WOFF2 support(experimental).
bashi@chromium.org6462c582014-06-27 06:24:49 +0000195// TODO(bashi): Remove WOFF2 from OTS.
ksakamoto@chromium.org74343ba2013-05-08 01:20:29 +0000196void EnableWOFF2();
197
bashi@chromium.org6462c582014-06-27 06:24:49 +0000198// Force to disable dropping CBDT/CBLC tables.
199void DoNotDropColorBitmapTables();
200
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000201} // namespace ots
202
203#endif // OPENTYPE_SANITISER_H_