1d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// Use of this source code is governed by a BSD-style license that can be 3d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// found in the LICENSE file. 4d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 5d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#ifndef OPENTYPE_SANITISER_H_ 6d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#define OPENTYPE_SANITISER_H_ 7d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 86a0c735027d75e13d03f286ffde9a696ee52d920agl@chromium.org#if defined(_WIN32) 998281afef95be7fee74edc8df7351f8b5e9969d1agl@chromium.org#include <stdlib.h> 10d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgtypedef signed char int8_t; 11d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgtypedef unsigned char uint8_t; 12d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgtypedef short int16_t; 13d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgtypedef unsigned short uint16_t; 14d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgtypedef int int32_t; 15d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgtypedef unsigned int uint32_t; 16d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgtypedef __int64 int64_t; 17d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgtypedef unsigned __int64 uint64_t; 1898281afef95be7fee74edc8df7351f8b5e9969d1agl@chromium.org#define ntohl(x) _byteswap_ulong (x) 1998281afef95be7fee74edc8df7351f8b5e9969d1agl@chromium.org#define ntohs(x) _byteswap_ushort (x) 2098281afef95be7fee74edc8df7351f8b5e9969d1agl@chromium.org#define htonl(x) _byteswap_ulong (x) 2198281afef95be7fee74edc8df7351f8b5e9969d1agl@chromium.org#define htons(x) _byteswap_ushort (x) 22d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#else 23d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#include <arpa/inet.h> 24d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#include <stdint.h> 25d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#endif 26d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 27d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#include <algorithm> // for std::min 28d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#include <cassert> 2918908189deb0ea39155f5558173862807e2936e1agl@chromium.org#include <cstddef> 30d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#include <cstring> 31d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 32d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgnamespace ots { 33d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 34d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// ----------------------------------------------------------------------------- 35d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// This is an interface for an abstract stream class which is used for writing 36d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// the serialised results out. 37d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// ----------------------------------------------------------------------------- 38d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgclass OTSStream { 39d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org public: 40d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org OTSStream() { 41d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org ResetChecksum(); 42d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 43d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 44d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org virtual ~OTSStream() {} 45d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 46d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org // This should be implemented to perform the actual write. 47d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org virtual bool WriteRaw(const void *data, size_t length) = 0; 48d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 49d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org bool Write(const void *data, size_t length) { 50d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org if (!length) return false; 51d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 52d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org const size_t orig_length = length; 53d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org size_t offset = 0; 54d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org if (chksum_buffer_offset_) { 55d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org const size_t l = 56d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org std::min(length, static_cast<size_t>(4) - chksum_buffer_offset_); 57d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org std::memcpy(chksum_buffer_ + chksum_buffer_offset_, data, l); 58d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org chksum_buffer_offset_ += l; 59d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org offset += l; 60d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org length -= l; 61d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 62d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 63d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org if (chksum_buffer_offset_ == 4) { 6419a629d15a4f78d5d37cee6aabdb71f7d9400ca6yusukes@chromium.org uint32_t chksum; 6519a629d15a4f78d5d37cee6aabdb71f7d9400ca6yusukes@chromium.org std::memcpy(&chksum, chksum_buffer_, 4); 6619a629d15a4f78d5d37cee6aabdb71f7d9400ca6yusukes@chromium.org chksum_ += ntohl(chksum); 67d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org chksum_buffer_offset_ = 0; 68d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 69d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 70d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org while (length >= 4) { 71d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org chksum_ += ntohl(*reinterpret_cast<const uint32_t*>( 72d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org reinterpret_cast<const uint8_t*>(data) + offset)); 73d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org length -= 4; 74d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org offset += 4; 75d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 76d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 77d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org if (length) { 78d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org if (chksum_buffer_offset_ != 0) return false; // not reached 79d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org if (length > 4) return false; // not reached 80d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org std::memcpy(chksum_buffer_, 81d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org reinterpret_cast<const uint8_t*>(data) + offset, length); 82d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org chksum_buffer_offset_ = length; 83d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 84d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 85d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return WriteRaw(data, orig_length); 86d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 87d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 88d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org virtual bool Seek(off_t position) = 0; 89d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org virtual off_t Tell() const = 0; 90d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 91d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org virtual bool Pad(size_t bytes) { 92d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org static const uint32_t kZero = 0; 93d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org while (bytes >= 4) { 94d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org if (!WriteTag(kZero)) return false; 95d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org bytes -= 4; 96d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 97d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org while (bytes) { 98d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org static const uint8_t kZerob = 0; 99d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org if (!Write(&kZerob, 1)) return false; 100d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org bytes--; 101d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 102d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return true; 103d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 104d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 10593aedf7d27cb93f93077f9f7f758e830a392bdfcbashi@google.com bool WriteU8(uint8_t v) { 10693aedf7d27cb93f93077f9f7f758e830a392bdfcbashi@google.com return Write(&v, sizeof(v)); 10793aedf7d27cb93f93077f9f7f758e830a392bdfcbashi@google.com } 10893aedf7d27cb93f93077f9f7f758e830a392bdfcbashi@google.com 109d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org bool WriteU16(uint16_t v) { 110d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org v = htons(v); 111d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return Write(&v, sizeof(v)); 112d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 113d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 114d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org bool WriteS16(int16_t v) { 115d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org v = htons(v); 116d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return Write(&v, sizeof(v)); 117d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 118d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 11993aedf7d27cb93f93077f9f7f758e830a392bdfcbashi@google.com bool WriteU24(uint32_t v) { 12093aedf7d27cb93f93077f9f7f758e830a392bdfcbashi@google.com v = htonl(v); 12193aedf7d27cb93f93077f9f7f758e830a392bdfcbashi@google.com return Write(reinterpret_cast<uint8_t*>(&v)+1, 3); 12293aedf7d27cb93f93077f9f7f758e830a392bdfcbashi@google.com } 12393aedf7d27cb93f93077f9f7f758e830a392bdfcbashi@google.com 124d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org bool WriteU32(uint32_t v) { 125d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org v = htonl(v); 126d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return Write(&v, sizeof(v)); 127d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 128d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 129d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org bool WriteS32(int32_t v) { 130d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org v = htonl(v); 131d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return Write(&v, sizeof(v)); 132d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 133d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 134d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org bool WriteR64(uint64_t v) { 135d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return Write(&v, sizeof(v)); 136d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 137d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 138d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org bool WriteTag(uint32_t v) { 139d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return Write(&v, sizeof(v)); 140d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 141d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 142d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org void ResetChecksum() { 143d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org chksum_ = 0; 144d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org chksum_buffer_offset_ = 0; 145d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 146d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 147d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org uint32_t chksum() const { 148d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org assert(chksum_buffer_offset_ == 0); 149d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return chksum_; 150d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 151d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 152d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org struct ChecksumState { 153d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org uint32_t chksum; 154d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org uint8_t chksum_buffer[4]; 155d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org unsigned chksum_buffer_offset; 156d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org }; 157d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 158d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org ChecksumState SaveChecksumState() const { 159d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org ChecksumState s; 160d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org s.chksum = chksum_; 161d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org s.chksum_buffer_offset = chksum_buffer_offset_; 162d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org std::memcpy(s.chksum_buffer, chksum_buffer_, 4); 163d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 164d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org return s; 165d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 166d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 167d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org void RestoreChecksum(const ChecksumState &s) { 168d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org assert(chksum_buffer_offset_ == 0); 169d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org chksum_ += s.chksum; 170d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org chksum_buffer_offset_ = s.chksum_buffer_offset; 171d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org std::memcpy(chksum_buffer_, s.chksum_buffer, 4); 172d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org } 173d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 174d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org protected: 175d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org uint32_t chksum_; 176d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org uint8_t chksum_buffer_[4]; 177d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org unsigned chksum_buffer_offset_; 178d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org}; 179d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 180d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// ----------------------------------------------------------------------------- 181d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// Process a given OpenType file and write out a sanitised version 182d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// output: a pointer to an object implementing the OTSStream interface. The 183d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// sanitisied output will be written to this. In the even of a failure, 184d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// partial output may have been written. 185d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// input: the OpenType file 186d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// length: the size, in bytes, of |input| 187d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// ----------------------------------------------------------------------------- 188d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgbool Process(OTSStream *output, const uint8_t *input, size_t length); 189d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 190d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// Force to disable debug output even when the library is compiled with 191d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org// -DOTS_DEBUG. 192d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgvoid DisableDebugOutput(); 193d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 19474343ba7bd420519a9a4f7b22977d7771286f6f8ksakamoto@chromium.org// Enable WOFF2 support(experimental). 19574343ba7bd420519a9a4f7b22977d7771286f6f8ksakamoto@chromium.orgvoid EnableWOFF2(); 19674343ba7bd420519a9a4f7b22977d7771286f6f8ksakamoto@chromium.org 197d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org} // namespace ots 198d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org 199d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org#endif // OPENTYPE_SANITISER_H_ 200