Compare commits

...

3 Commits

Author SHA1 Message Date
69853a3f68 More cleanups. 2023-12-17 20:11:13 +01:00
59a6cc90f4 Removed freetype. 2023-12-17 20:02:51 +01:00
5d0ce5dc5e Removed the enet module. 2023-12-17 20:01:11 +01:00
528 changed files with 1 additions and 243539 deletions

View File

@ -6,7 +6,6 @@
#include "core/config/project_settings.h"
#include "core/crypto/crypto_core.h"
#include "core/io/file_access_encrypted.h"
#include "core/io/json.h"
#include "core/io/marshalls.h"
#include "core/math/geometry.h"

View File

@ -4,7 +4,6 @@
#include "config_file.h"
#include "core/io/file_access_encrypted.h"
#include "core/os/keyboard.h"
#include "core/variant/variant_parser.h"
@ -111,43 +110,6 @@ Error ConfigFile::save(const String &p_path) {
return _internal_save(file);
}
Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) {
return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_WRITE_AES256);
if (err) {
memdelete(fae);
memdelete(f);
return err;
}
return _internal_save(fae);
}
Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass) {
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) {
return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_WRITE_AES256);
if (err) {
memdelete(fae);
memdelete(f);
return err;
}
return _internal_save(fae);
}
Error ConfigFile::_internal_save(FileAccess *file) {
for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::Element E = values.front(); E; E = E.next()) {
if (E != values.front()) {
@ -178,43 +140,6 @@ Error ConfigFile::load(const String &p_path) {
return _internal_load(p_path, f);
}
Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) {
return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_READ);
if (err) {
memdelete(fae);
memdelete(f);
return err;
}
return _internal_load(p_path, fae);
}
Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass) {
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) {
return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_READ);
if (err) {
memdelete(fae);
memdelete(f);
return err;
}
return _internal_load(p_path, fae);
}
Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) {
VariantParser::StreamFile stream;
stream.f = f;
@ -285,11 +210,5 @@ void ConfigFile::_bind_methods() {
ClassDB::bind_method(D_METHOD("parse", "data"), &ConfigFile::parse);
ClassDB::bind_method(D_METHOD("save", "path"), &ConfigFile::save);
ClassDB::bind_method(D_METHOD("load_encrypted", "path", "key"), &ConfigFile::load_encrypted);
ClassDB::bind_method(D_METHOD("load_encrypted_pass", "path", "password"), &ConfigFile::load_encrypted_pass);
ClassDB::bind_method(D_METHOD("save_encrypted", "path", "key"), &ConfigFile::save_encrypted);
ClassDB::bind_method(D_METHOD("save_encrypted_pass", "path", "password"), &ConfigFile::save_encrypted_pass);
ClassDB::bind_method(D_METHOD("clear"), &ConfigFile::clear);
}

View File

@ -42,12 +42,6 @@ public:
Error parse(const String &p_data);
void clear();
Error load_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
Error load_encrypted_pass(const String &p_path, const String &p_pass);
Error save_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
Error save_encrypted_pass(const String &p_path, const String &p_pass);
};
#endif // CONFIG_FILE_H

View File

@ -1,29 +0,0 @@
/* dtls_server.cpp */
#include "dtls_server.h"
#include "core/os/file_access.h"
#include "core/config/project_settings.h"
DTLSServer *(*DTLSServer::_create)() = nullptr;
bool DTLSServer::available = false;
DTLSServer *DTLSServer::create() {
if (_create) {
return _create();
}
return nullptr;
}
bool DTLSServer::is_available() {
return available;
}
void DTLSServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("setup", "key", "certificate", "chain"), &DTLSServer::setup, DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_method(D_METHOD("take_connection", "udp_peer"), &DTLSServer::take_connection);
}
DTLSServer::DTLSServer() {
}

View File

@ -1,30 +0,0 @@
#ifndef DTLS_SERVER_H
#define DTLS_SERVER_H
/* dtls_server.h */
#include "core/io/net_socket.h"
#include "core/io/packet_peer_dtls.h"
class DTLSServer : public Reference {
GDCLASS(DTLSServer, Reference);
protected:
static DTLSServer *(*_create)();
static void _bind_methods();
static bool available;
public:
static bool is_available();
static DTLSServer *create();
virtual Error setup(Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>()) = 0;
virtual void stop() = 0;
virtual Ref<PacketPeerDTLS> take_connection(Ref<PacketPeerUDP> p_peer) = 0;
DTLSServer();
};
#endif // DTLS_SERVER_H

View File

@ -1,283 +0,0 @@
/* file_access_encrypted.cpp */
#include "file_access_encrypted.h"
#include "core/crypto/crypto_core.h"
#include "core/string/print_string.h"
#include "core/variant/variant.h"
#include <stdio.h>
#define COMP_MAGIC 0x43454447
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) {
ERR_FAIL_COND_V_MSG(file != nullptr, ERR_ALREADY_IN_USE, "Can't open file while another file from path '" + file->get_path_absolute() + "' is open.");
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
pos = 0;
eofed = false;
if (p_mode == MODE_WRITE_AES256) {
data.clear();
writing = true;
file = p_base;
mode = p_mode;
key = p_key;
} else if (p_mode == MODE_READ) {
writing = false;
key = p_key;
uint32_t magic = p_base->get_32();
ERR_FAIL_COND_V(magic != COMP_MAGIC, ERR_FILE_UNRECOGNIZED);
mode = Mode(p_base->get_32());
ERR_FAIL_INDEX_V(mode, MODE_MAX, ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(mode == 0, ERR_FILE_CORRUPT);
unsigned char md5d[16];
p_base->get_buffer(md5d, 16);
length = p_base->get_64();
base = p_base->get_position();
ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT);
uint64_t ds = length;
if (ds % 16) {
ds += 16 - (ds % 16);
}
data.resize(ds);
uint64_t blen = p_base->get_buffer(data.ptrw(), ds);
ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT);
CryptoCore::AESContext ctx;
ctx.set_decode_key(key.ptrw(), 256);
for (uint64_t i = 0; i < ds; i += 16) {
ctx.decrypt_ecb(&data.write[i], &data.write[i]);
}
data.resize(length);
unsigned char hash[16];
ERR_FAIL_COND_V(CryptoCore::md5(data.ptr(), data.size(), hash) != OK, ERR_BUG);
ERR_FAIL_COND_V_MSG(String::md5(hash) != String::md5(md5d), ERR_FILE_CORRUPT, "The MD5 sum of the decrypted file does not match the expected value. It could be that the file is corrupt, or that the provided decryption key is invalid.");
file = p_base;
}
return OK;
}
Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode) {
String cs = p_key.md5_text();
ERR_FAIL_COND_V(cs.length() != 32, ERR_INVALID_PARAMETER);
Vector<uint8_t> key;
key.resize(32);
for (int i = 0; i < 32; i++) {
key.write[i] = cs[i];
}
return open_and_parse(p_base, key, p_mode);
}
Error FileAccessEncrypted::_open(const String &p_path, int p_mode_flags) {
return OK;
}
void FileAccessEncrypted::close() {
if (!file) {
return;
}
if (writing) {
Vector<uint8_t> compressed;
uint64_t len = data.size();
if (len % 16) {
len += 16 - (len % 16);
}
unsigned char hash[16];
ERR_FAIL_COND(CryptoCore::md5(data.ptr(), data.size(), hash) != OK); // Bug?
compressed.resize(len);
memset(compressed.ptrw(), 0, len);
for (int i = 0; i < data.size(); i++) {
compressed.write[i] = data[i];
}
CryptoCore::AESContext ctx;
ctx.set_encode_key(key.ptrw(), 256);
for (uint64_t i = 0; i < len; i += 16) {
ctx.encrypt_ecb(&compressed.write[i], &compressed.write[i]);
}
file->store_32(COMP_MAGIC);
file->store_32(mode);
file->store_buffer(hash, 16);
file->store_64(data.size());
file->store_buffer(compressed.ptr(), compressed.size());
file->close();
memdelete(file);
file = nullptr;
data.clear();
} else {
file->close();
memdelete(file);
data.clear();
file = nullptr;
}
}
bool FileAccessEncrypted::is_open() const {
return file != nullptr;
}
String FileAccessEncrypted::get_path() const {
if (file) {
return file->get_path();
} else {
return "";
}
}
String FileAccessEncrypted::get_path_absolute() const {
if (file) {
return file->get_path_absolute();
} else {
return "";
}
}
void FileAccessEncrypted::seek(uint64_t p_position) {
if (p_position > get_len()) {
p_position = get_len();
}
pos = p_position;
eofed = false;
}
void FileAccessEncrypted::seek_end(int64_t p_position) {
seek(get_len() + p_position);
}
uint64_t FileAccessEncrypted::get_position() const {
return pos;
}
uint64_t FileAccessEncrypted::get_len() const {
return data.size();
}
bool FileAccessEncrypted::eof_reached() const {
return eofed;
}
uint8_t FileAccessEncrypted::get_8() const {
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
if (pos >= get_len()) {
eofed = true;
return 0;
}
uint8_t b = data[pos];
pos++;
return b;
}
uint64_t FileAccessEncrypted::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode.");
uint64_t to_copy = MIN(p_length, get_len() - pos);
for (uint64_t i = 0; i < to_copy; i++) {
p_dst[i] = data[pos++];
}
if (to_copy < p_length) {
eofed = true;
}
return to_copy;
}
Error FileAccessEncrypted::get_error() const {
return eofed ? ERR_FILE_EOF : OK;
}
void FileAccessEncrypted::store_buffer(const uint8_t *p_src, uint64_t p_length) {
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
ERR_FAIL_COND(!p_src && p_length > 0);
if (pos < get_len()) {
for (uint64_t i = 0; i < p_length; i++) {
store_8(p_src[i]);
}
} else if (pos == get_len()) {
data.resize(pos + p_length);
for (uint64_t i = 0; i < p_length; i++) {
data.write[pos + i] = p_src[i];
}
pos += p_length;
}
}
void FileAccessEncrypted::flush() {
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
// encrypted files keep data in memory till close()
}
void FileAccessEncrypted::store_8(uint8_t p_dest) {
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
if (pos < get_len()) {
data.write[pos] = p_dest;
pos++;
} else if (pos == get_len()) {
data.push_back(p_dest);
pos++;
}
}
bool FileAccessEncrypted::file_exists(const String &p_name) {
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
if (!fa) {
return false;
}
memdelete(fa);
return true;
}
uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
return 0;
}
uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
return 0;
}
Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
ERR_PRINT("Setting UNIX permissions on encrypted files is not implemented yet.");
return ERR_UNAVAILABLE;
}
FileAccessEncrypted::FileAccessEncrypted() {
file = nullptr;
pos = 0;
eofed = false;
mode = MODE_MAX;
writing = false;
}
FileAccessEncrypted::~FileAccessEncrypted() {
if (file) {
close();
}
}

View File

@ -1,65 +0,0 @@
#ifndef FILE_ACCESS_ENCRYPTED_H
#define FILE_ACCESS_ENCRYPTED_H
/* file_access_encrypted.h */
#include "core/os/file_access.h"
class FileAccessEncrypted : public FileAccess {
public:
enum Mode {
MODE_READ,
MODE_WRITE_AES256,
MODE_MAX
};
private:
Mode mode;
Vector<uint8_t> key;
bool writing;
FileAccess *file;
uint64_t base;
uint64_t length;
Vector<uint8_t> data;
mutable uint64_t pos;
mutable bool eofed;
public:
Error open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode);
Error open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode);
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual String get_path() const; /// returns the path for the current open file
virtual String get_path_absolute() const; /// returns the absolute path for the current open file
virtual void seek(uint64_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual uint64_t get_position() const; ///< get position in the file
virtual uint64_t get_len() const; ///< get size of the file
virtual bool eof_reached() const; ///< reading passed EOF
virtual uint8_t get_8() const; ///< get a byte
virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const;
virtual Error get_error() const; ///< get last error
virtual void flush();
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file);
virtual uint32_t _get_unix_permissions(const String &p_file);
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
FileAccessEncrypted();
~FileAccessEncrypted();
};
#endif // FILE_ACCESS_ENCRYPTED_H

View File

@ -15,7 +15,6 @@
#include "core/input/input.h"
#include "core/input/input_map.h"
#include "core/io/config_file.h"
#include "core/io/dtls_server.h"
#include "core/io/http_client.h"
#include "core/io/image_loader.h"
#include "core/io/marshalls.h"
@ -142,7 +141,6 @@ void register_core_types() {
ClassDB::register_class<PacketPeerUDP>();
ClassDB::register_class<UDPServer>();
ClassDB::register_custom_instance_class<PacketPeerDTLS>();
ClassDB::register_custom_instance_class<DTLSServer>();
// Crypto
ClassDB::register_class<HashingContext>();

View File

@ -1,43 +0,0 @@
#!/usr/bin/env python
Import("env")
Import("env_modules")
env_enet = env_modules.Clone()
# Thirdparty source files
thirdparty_obj = []
if env["builtin_enet"]:
thirdparty_dir = "enet/"
thirdparty_sources = [
"pandemonium.cpp",
"callbacks.c",
"compress.c",
"host.c",
"list.c",
"packet.c",
"peer.c",
"protocol.c",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env_enet.Prepend(CPPPATH=[thirdparty_dir])
env_enet.Append(CPPDEFINES=["PANDEMONIUM_ENET"])
env_thirdparty = env_enet.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
env.modules_sources += thirdparty_obj
# Pandemonium source files
module_obj = []
env_enet.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj
# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)

View File

@ -1,16 +0,0 @@
def can_build(env, platform):
return True
def configure(env):
pass
def get_doc_classes():
return [
"NetworkedMultiplayerENet",
]
def get_doc_path():
return "doc_classes"

View File

@ -1,138 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NetworkedMultiplayerENet" inherits="NetworkedMultiplayerPeer" version="4.2">
<brief_description>
PacketPeer implementation using the [url=http://enet.bespin.org/index.html]ENet[/url] library.
</brief_description>
<description>
A PacketPeer implementation that should be passed to [member SceneTree.network_peer] after being initialized as either a client or server. Events can then be handled by connecting to [SceneTree] signals.
ENet's purpose is to provide a relatively thin, simple and robust network communication layer on top of UDP (User Datagram Protocol).
[b]Note:[/b] ENet only uses UDP, not TCP. When forwarding the server port to make your server accessible on the public Internet, you only need to forward the server port in UDP. You can use the [UPNP] class to try to forward the server port automatically when starting the server.
</description>
<tutorials>
<link>$DOCS_URL/tutorials/networking/high_level_multiplayer.md</link>
<link>http://enet.bespin.org/usergroup0.html</link>
</tutorials>
<methods>
<method name="close_connection">
<return type="void" />
<argument index="0" name="wait_usec" type="int" default="100" />
<description>
Closes the connection. Ignored if no connection is currently established. If this is a server it tries to notify all clients before forcibly disconnecting them. If this is a client it simply closes the connection to the server.
</description>
</method>
<method name="create_client">
<return type="int" enum="Error" />
<argument index="0" name="address" type="String" />
<argument index="1" name="port" type="int" />
<argument index="2" name="in_bandwidth" type="int" default="0" />
<argument index="3" name="out_bandwidth" type="int" default="0" />
<argument index="4" name="client_port" type="int" default="0" />
<description>
Create client that connects to a server at [code]address[/code] using specified [code]port[/code]. The given address needs to be either a fully qualified domain name (e.g. [code]"www.example.com"[/code]) or an IP address in IPv4 or IPv6 format (e.g. [code]"192.168.1.1"[/code]). The [code]port[/code] is the port the server is listening on. The [code]in_bandwidth[/code] and [code]out_bandwidth[/code] parameters can be used to limit the incoming and outgoing bandwidth to the given number of bytes per second. The default of 0 means unlimited bandwidth. Note that ENet will strategically drop packets on specific sides of a connection between peers to ensure the peer's bandwidth is not overwhelmed. The bandwidth parameters also determine the window size of a connection which limits the amount of reliable packets that may be in transit at any given time. Returns [constant OK] if a client was created, [constant ERR_ALREADY_IN_USE] if this NetworkedMultiplayerENet instance already has an open connection (in which case you need to call [method close_connection] first) or [constant ERR_CANT_CREATE] if the client could not be created. If [code]client_port[/code] is specified, the client will also listen to the given port; this is useful for some NAT traversal techniques.
</description>
</method>
<method name="create_server">
<return type="int" enum="Error" />
<argument index="0" name="port" type="int" />
<argument index="1" name="max_clients" type="int" default="32" />
<argument index="2" name="in_bandwidth" type="int" default="0" />
<argument index="3" name="out_bandwidth" type="int" default="0" />
<description>
Create server that listens to connections via [code]port[/code]. The port needs to be an available, unused port between 0 and 65535. Note that ports below 1024 are privileged and may require elevated permissions depending on the platform. To change the interface the server listens on, use [method set_bind_ip]. The default IP is the wildcard [code]"*"[/code], which listens on all available interfaces. [code]max_clients[/code] is the maximum number of clients that are allowed at once, any number up to 4095 may be used, although the achievable number of simultaneous clients may be far lower and depends on the application. For additional details on the bandwidth parameters, see [method create_client]. Returns [constant OK] if a server was created, [constant ERR_ALREADY_IN_USE] if this NetworkedMultiplayerENet instance already has an open connection (in which case you need to call [method close_connection] first) or [constant ERR_CANT_CREATE] if the server could not be created.
</description>
</method>
<method name="disconnect_peer">
<return type="void" />
<argument index="0" name="id" type="int" />
<argument index="1" name="now" type="bool" default="false" />
<description>
Disconnect the given peer. If "now" is set to [code]true[/code], the connection will be closed immediately without flushing queued messages.
</description>
</method>
<method name="get_last_packet_channel" qualifiers="const">
<return type="int" />
<description>
Returns the channel of the last packet fetched via [method PacketPeer.get_packet].
</description>
</method>
<method name="get_packet_channel" qualifiers="const">
<return type="int" />
<description>
Returns the channel of the next packet that will be retrieved via [method PacketPeer.get_packet].
</description>
</method>
<method name="get_peer_address" qualifiers="const">
<return type="String" />
<argument index="0" name="id" type="int" />
<description>
Returns the IP address of the given peer.
</description>
</method>
<method name="get_peer_port" qualifiers="const">
<return type="int" />
<argument index="0" name="id" type="int" />
<description>
Returns the remote port of the given peer.
</description>
</method>
<method name="set_bind_ip">
<return type="void" />
<argument index="0" name="ip" type="String" />
<description>
The IP used when creating a server. This is set to the wildcard [code]"*"[/code] by default, which binds to all available interfaces. The given IP needs to be in IPv4 or IPv6 address format, for example: [code]"192.168.1.1"[/code].
</description>
</method>
<method name="set_dtls_certificate">
<return type="void" />
<argument index="0" name="certificate" type="X509Certificate" />
<description>
Configure the [X509Certificate] to use when [member use_dtls] is [code]true[/code]. For servers, you must also setup the [CryptoKey] via [method set_dtls_key].
</description>
</method>
<method name="set_dtls_key">
<return type="void" />
<argument index="0" name="key" type="CryptoKey" />
<description>
Configure the [CryptoKey] to use when [member use_dtls] is [code]true[/code]. Remember to also call [method set_dtls_certificate] to setup your [X509Certificate].
</description>
</method>
<method name="set_peer_timeout">
<return type="void" />
<argument index="0" name="id" type="int" />
<argument index="1" name="timeout_limit" type="int" />
<argument index="2" name="timeout_min" type="int" />
<argument index="3" name="timeout_max" type="int" />
<description>
Sets the timeout parameters for a peer. The timeout parameters control how and when a peer will timeout from a failure to acknowledge reliable traffic. Timeout values are expressed in milliseconds.
The [code]timeout_limit[/code] is a factor that, multiplied by a value based on the average round trip time, will determine the timeout limit for a reliable packet. When that limit is reached, the timeout will be doubled, and the peer will be disconnected if that limit has reached [code]timeout_min[/code]. The [code]timeout_max[/code] parameter, on the other hand, defines a fixed timeout for which any packet must be acknowledged or the peer will be dropped.
</description>
</method>
</methods>
<members>
<member name="always_ordered" type="bool" setter="set_always_ordered" getter="is_always_ordered" default="false">
Enforce ordered packets when using [constant NetworkedMultiplayerPeer.TRANSFER_MODE_UNRELIABLE] (thus behaving similarly to [constant NetworkedMultiplayerPeer.TRANSFER_MODE_UNRELIABLE_ORDERED]). This is the only way to use ordering with the RPC system.
</member>
<member name="channel_count" type="int" setter="set_channel_count" getter="get_channel_count" default="3">
The number of channels to be used by ENet. Channels are used to separate different kinds of data. In reliable or ordered mode, for example, the packet delivery order is ensured on a per-channel basis. This is done to combat latency and reduces ordering restrictions on packets. The delivery status of a packet in one channel won't stall the delivery of other packets in another channel.
</member>
<member name="dtls_hostname" type="String" setter="set_dtls_hostname" getter="get_dtls_hostname" default="&quot;&quot;">
The hostname used for DTLS verification, to be compared against the "CN" value in the certificate provided by the server.
When set to an empty string, the [code]address[/code] parameter passed to [method create_client] is used instead.
</member>
<member name="dtls_verify" type="bool" setter="set_dtls_verify_enabled" getter="is_dtls_verify_enabled" default="true">
Enable or disable certificate verification when [member use_dtls] [code]true[/code].
</member>
<member name="server_relay" type="bool" setter="set_server_relay_enabled" getter="is_server_relay_enabled" default="true">
Enable or disable the server feature that notifies clients of other peers' connection/disconnection, and relays messages between them. When this option is [code]false[/code], clients won't be automatically notified of other peers and won't be able to send them packets through the server.
</member>
<member name="transfer_channel" type="int" setter="set_transfer_channel" getter="get_transfer_channel" default="-1">
Set the default channel to be used to transfer data. By default, this value is [code]-1[/code] which means that ENet will only use 2 channels: one for reliable packets, and one for unreliable packets. The channel [code]0[/code] is reserved and cannot be used. Setting this member to any value between [code]0[/code] and [member channel_count] (excluded) will force ENet to use that channel for sending data. See [member channel_count] for more information about ENet channels.
</member>
<member name="use_dtls" type="bool" setter="set_dtls_enabled" getter="is_dtls_enabled" default="false">
When enabled, the client or server created by this peer, will use [PacketPeerDTLS] instead of raw UDP sockets for communicating with the remote peer. This will make the communication encrypted with DTLS at the cost of higher resource usage and potentially larger packet size.
[b]Note:[/b] When creating a DTLS server, make sure you setup the key/certificate pair via [method set_dtls_key] and [method set_dtls_certificate]. For DTLS clients, have a look at the [member dtls_verify] option, and configure the certificate accordingly via [method set_dtls_certificate].
</member>
</members>
<constants>
</constants>
</class>

View File

@ -1,7 +0,0 @@
Copyright (c) 2002-2020 Lee Salzman
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,53 +0,0 @@
/**
@file callbacks.c
@brief ENet callback functions
*/
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
static ENetCallbacks callbacks = { malloc, free, abort };
int
enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits)
{
if (version < ENET_VERSION_CREATE (1, 3, 0))
return -1;
if (inits -> malloc != NULL || inits -> free != NULL)
{
if (inits -> malloc == NULL || inits -> free == NULL)
return -1;
callbacks.malloc = inits -> malloc;
callbacks.free = inits -> free;
}
if (inits -> no_memory != NULL)
callbacks.no_memory = inits -> no_memory;
return enet_initialize ();
}
ENetVersion
enet_linked_version (void)
{
return ENET_VERSION;
}
void *
enet_malloc (size_t size)
{
void * memory = callbacks.malloc (size);
if (memory == NULL)
callbacks.no_memory ();
return memory;
}
void
enet_free (void * memory)
{
callbacks.free (memory);
}

View File

@ -1,654 +0,0 @@
/**
@file compress.c
@brief An adaptive order-2 PPM range coder
*/
#define ENET_BUILDING_LIB 1
#include <string.h>
#include "enet/enet.h"
typedef struct _ENetSymbol
{
/* binary indexed tree of symbols */
enet_uint8 value;
enet_uint8 count;
enet_uint16 under;
enet_uint16 left, right;
/* context defined by this symbol */
enet_uint16 symbols;
enet_uint16 escapes;
enet_uint16 total;
enet_uint16 parent;
} ENetSymbol;
/* adaptation constants tuned aggressively for small packet sizes rather than large file compression */
enum
{
ENET_RANGE_CODER_TOP = 1<<24,
ENET_RANGE_CODER_BOTTOM = 1<<16,
ENET_CONTEXT_SYMBOL_DELTA = 3,
ENET_CONTEXT_SYMBOL_MINIMUM = 1,
ENET_CONTEXT_ESCAPE_MINIMUM = 1,
ENET_SUBCONTEXT_ORDER = 2,
ENET_SUBCONTEXT_SYMBOL_DELTA = 2,
ENET_SUBCONTEXT_ESCAPE_DELTA = 5
};
/* context exclusion roughly halves compression speed, so disable for now */
#undef ENET_CONTEXT_EXCLUSION
typedef struct _ENetRangeCoder
{
/* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */
ENetSymbol symbols[4096];
} ENetRangeCoder;
void *
enet_range_coder_create (void)
{
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder));
if (rangeCoder == NULL)
return NULL;
return rangeCoder;
}
void
enet_range_coder_destroy (void * context)
{
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
if (rangeCoder == NULL)
return;
enet_free (rangeCoder);
}
#define ENET_SYMBOL_CREATE(symbol, value_, count_) \
{ \
symbol = & rangeCoder -> symbols [nextSymbol ++]; \
symbol -> value = value_; \
symbol -> count = count_; \
symbol -> under = count_; \
symbol -> left = 0; \
symbol -> right = 0; \
symbol -> symbols = 0; \
symbol -> escapes = 0; \
symbol -> total = 0; \
symbol -> parent = 0; \
}
#define ENET_CONTEXT_CREATE(context, escapes_, minimum) \
{ \
ENET_SYMBOL_CREATE (context, 0, 0); \
(context) -> escapes = escapes_; \
(context) -> total = escapes_ + 256*minimum; \
(context) -> symbols = 0; \
}
static enet_uint16
enet_symbol_rescale (ENetSymbol * symbol)
{
enet_uint16 total = 0;
for (;;)
{
symbol -> count -= symbol->count >> 1;
symbol -> under = symbol -> count;
if (symbol -> left)
symbol -> under += enet_symbol_rescale (symbol + symbol -> left);
total += symbol -> under;
if (! symbol -> right) break;
symbol += symbol -> right;
}
return total;
}
#define ENET_CONTEXT_RESCALE(context, minimum) \
{ \
(context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \
(context) -> escapes -= (context) -> escapes >> 1; \
(context) -> total += (context) -> escapes + 256*minimum; \
}
#define ENET_RANGE_CODER_OUTPUT(value) \
{ \
if (outData >= outEnd) \
return 0; \
* outData ++ = value; \
}
#define ENET_RANGE_CODER_ENCODE(under, count, total) \
{ \
encodeRange /= (total); \
encodeLow += (under) * encodeRange; \
encodeRange *= (count); \
for (;;) \
{ \
if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \
{ \
if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
} \
ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
encodeRange <<= 8; \
encodeLow <<= 8; \
} \
}
#define ENET_RANGE_CODER_FLUSH \
{ \
while (encodeLow) \
{ \
ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
encodeLow <<= 8; \
} \
}
#define ENET_RANGE_CODER_FREE_SYMBOLS \
{ \
if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \
{ \
nextSymbol = 0; \
ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \
predicted = 0; \
order = 0; \
} \
}
#define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \
{ \
under_ = value*minimum; \
count_ = minimum; \
if (! (context) -> symbols) \
{ \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
(context) -> symbols = symbol_ - (context); \
} \
else \
{ \
ENetSymbol * node = (context) + (context) -> symbols; \
for (;;) \
{ \
if (value_ < node -> value) \
{ \
node -> under += update; \
if (node -> left) { node += node -> left; continue; } \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
node -> left = symbol_ - node; \
} \
else \
if (value_ > node -> value) \
{ \
under_ += node -> under; \
if (node -> right) { node += node -> right; continue; } \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
node -> right = symbol_ - node; \
} \
else \
{ \
count_ += node -> count; \
under_ += node -> under - node -> count; \
node -> under += update; \
node -> count += update; \
symbol_ = node; \
} \
break; \
} \
} \
}
#ifdef ENET_CONTEXT_EXCLUSION
static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
#define ENET_CONTEXT_WALK(context, body) \
{ \
const ENetSymbol * node = (context) + (context) -> symbols; \
const ENetSymbol * stack [256]; \
size_t stackSize = 0; \
while (node -> left) \
{ \
stack [stackSize ++] = node; \
node += node -> left; \
} \
for (;;) \
{ \
body; \
if (node -> right) \
{ \
node += node -> right; \
while (node -> left) \
{ \
stack [stackSize ++] = node; \
node += node -> left; \
} \
} \
else \
if (stackSize <= 0) \
break; \
else \
node = stack [-- stackSize]; \
} \
}
#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \
ENET_CONTEXT_WALK(context, { \
if (node -> value != value_) \
{ \
enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \
if (node -> value < value_) \
under -= parentCount; \
total -= parentCount; \
} \
})
#endif
size_t
enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit)
{
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
const enet_uint8 * inData, * inEnd;
enet_uint32 encodeLow = 0, encodeRange = ~0;
ENetSymbol * root;
enet_uint16 predicted = 0;
size_t order = 0, nextSymbol = 0;
if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0)
return 0;
inData = (const enet_uint8 *) inBuffers -> data;
inEnd = & inData [inBuffers -> dataLength];
inBuffers ++;
inBufferCount --;
ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
for (;;)
{
ENetSymbol * subcontext, * symbol;
#ifdef ENET_CONTEXT_EXCLUSION
const ENetSymbol * childContext = & emptyContext;
#endif
enet_uint8 value;
enet_uint16 count, under, * parent = & predicted, total;
if (inData >= inEnd)
{
if (inBufferCount <= 0)
break;
inData = (const enet_uint8 *) inBuffers -> data;
inEnd = & inData [inBuffers -> dataLength];
inBuffers ++;
inBufferCount --;
}
value = * inData ++;
for (subcontext = & rangeCoder -> symbols [predicted];
subcontext != root;
#ifdef ENET_CONTEXT_EXCLUSION
childContext = subcontext,
#endif
subcontext = & rangeCoder -> symbols [subcontext -> parent])
{
ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
* parent = symbol - rangeCoder -> symbols;
parent = & symbol -> parent;
total = subcontext -> total;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0);
#endif
if (count > 0)
{
ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total);
}
else
{
if (subcontext -> escapes > 0 && subcontext -> escapes < total)
ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total);
subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
}
subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (subcontext, 0);
if (count > 0) goto nextInput;
}
ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM);
* parent = symbol - rangeCoder -> symbols;
parent = & symbol -> parent;
total = root -> total;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM);
#endif
ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total);
root -> total += ENET_CONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
nextInput:
if (order >= ENET_SUBCONTEXT_ORDER)
predicted = rangeCoder -> symbols [predicted].parent;
else
order ++;
ENET_RANGE_CODER_FREE_SYMBOLS;
}
ENET_RANGE_CODER_FLUSH;
return (size_t) (outData - outStart);
}
#define ENET_RANGE_CODER_SEED \
{ \
if (inData < inEnd) decodeCode |= * inData ++ << 24; \
if (inData < inEnd) decodeCode |= * inData ++ << 16; \
if (inData < inEnd) decodeCode |= * inData ++ << 8; \
if (inData < inEnd) decodeCode |= * inData ++; \
}
#define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total)))
#define ENET_RANGE_CODER_DECODE(under, count, total) \
{ \
decodeLow += (under) * decodeRange; \
decodeRange *= (count); \
for (;;) \
{ \
if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \
{ \
if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
} \
decodeCode <<= 8; \
if (inData < inEnd) \
decodeCode |= * inData ++; \
decodeRange <<= 8; \
decodeLow <<= 8; \
} \
}
#define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \
{ \
under_ = 0; \
count_ = minimum; \
if (! (context) -> symbols) \
{ \
createRoot; \
} \
else \
{ \
ENetSymbol * node = (context) + (context) -> symbols; \
for (;;) \
{ \
enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \
visitNode; \
if (code >= after) \
{ \
under_ += node -> under; \
if (node -> right) { node += node -> right; continue; } \
createRight; \
} \
else \
if (code < after - before) \
{ \
node -> under += update; \
if (node -> left) { node += node -> left; continue; } \
createLeft; \
} \
else \
{ \
value_ = node -> value; \
count_ += node -> count; \
under_ = after - before; \
node -> under += update; \
node -> count += update; \
symbol_ = node; \
} \
break; \
} \
} \
}
#define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0)
#define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \
{ \
value_ = code / minimum; \
under_ = code - code%minimum; \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
(context) -> symbols = symbol_ - (context); \
}, \
exclude (node -> value, after, before), \
{ \
value_ = node->value + 1 + (code - after)/minimum; \
under_ = code - (code - after)%minimum; \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
node -> right = symbol_ - node; \
}, \
{ \
value_ = node->value - 1 - (after - before - code - 1)/minimum; \
under_ = code - (after - before - code - 1)%minimum; \
ENET_SYMBOL_CREATE (symbol_, value_, update); \
node -> left = symbol_ - node; \
}) \
#ifdef ENET_CONTEXT_EXCLUSION
typedef struct _ENetExclude
{
enet_uint8 value;
enet_uint16 under;
} ENetExclude;
#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \
{ \
enet_uint16 under = 0; \
nextExclude = excludes; \
ENET_CONTEXT_WALK (context, { \
under += rangeCoder -> symbols [node -> parent].count + minimum; \
nextExclude -> value = node -> value; \
nextExclude -> under = under; \
nextExclude ++; \
}); \
total -= under; \
}
#define ENET_CONTEXT_EXCLUDED(value_, after, before) \
{ \
size_t low = 0, high = nextExclude - excludes; \
for(;;) \
{ \
size_t mid = (low + high) >> 1; \
const ENetExclude * exclude = & excludes [mid]; \
if (value_ < exclude -> value) \
{ \
if (low + 1 < high) \
{ \
high = mid; \
continue; \
} \
if (exclude > excludes) \
after -= exclude [-1].under; \
} \
else \
{ \
if (value_ > exclude -> value) \
{ \
if (low + 1 < high) \
{ \
low = mid; \
continue; \
} \
} \
else \
before = 0; \
after -= exclude -> under; \
} \
break; \
} \
}
#endif
#define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before)
size_t
enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit)
{
ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
const enet_uint8 * inEnd = & inData [inLimit];
enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0;
ENetSymbol * root;
enet_uint16 predicted = 0;
size_t order = 0, nextSymbol = 0;
#ifdef ENET_CONTEXT_EXCLUSION
ENetExclude excludes [256];
ENetExclude * nextExclude = excludes;
#endif
if (rangeCoder == NULL || inLimit <= 0)
return 0;
ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
ENET_RANGE_CODER_SEED;
for (;;)
{
ENetSymbol * subcontext, * symbol, * patch;
#ifdef ENET_CONTEXT_EXCLUSION
const ENetSymbol * childContext = & emptyContext;
#endif
enet_uint8 value = 0;
enet_uint16 code, under, count, bottom, * parent = & predicted, total;
for (subcontext = & rangeCoder -> symbols [predicted];
subcontext != root;
#ifdef ENET_CONTEXT_EXCLUSION
childContext = subcontext,
#endif
subcontext = & rangeCoder -> symbols [subcontext -> parent])
{
if (subcontext -> escapes <= 0)
continue;
total = subcontext -> total;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > 0)
ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0);
#endif
if (subcontext -> escapes >= total)
continue;
code = ENET_RANGE_CODER_READ (total);
if (code < subcontext -> escapes)
{
ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total);
continue;
}
code -= subcontext -> escapes;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > 0)
{
ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED);
}
else
#endif
{
ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED);
}
bottom = symbol - rangeCoder -> symbols;
ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total);
subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (subcontext, 0);
goto patchContexts;
}
total = root -> total;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > 0)
ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM);
#endif
code = ENET_RANGE_CODER_READ (total);
if (code < root -> escapes)
{
ENET_RANGE_CODER_DECODE (0, root -> escapes, total);
break;
}
code -= root -> escapes;
#ifdef ENET_CONTEXT_EXCLUSION
if (childContext -> total > 0)
{
ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED);
}
else
#endif
{
ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED);
}
bottom = symbol - rangeCoder -> symbols;
ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total);
root -> total += ENET_CONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
patchContexts:
for (patch = & rangeCoder -> symbols [predicted];
patch != subcontext;
patch = & rangeCoder -> symbols [patch -> parent])
{
ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
* parent = symbol - rangeCoder -> symbols;
parent = & symbol -> parent;
if (count <= 0)
{
patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
}
patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
ENET_CONTEXT_RESCALE (patch, 0);
}
* parent = bottom;
ENET_RANGE_CODER_OUTPUT (value);
if (order >= ENET_SUBCONTEXT_ORDER)
predicted = rangeCoder -> symbols [predicted].parent;
else
order ++;
ENET_RANGE_CODER_FREE_SYMBOLS;
}
return (size_t) (outData - outStart);
}
/** @defgroup host ENet host functions
@{
*/
/** Sets the packet compressor the host should use to the default range coder.
@param host host to enable the range coder for
@returns 0 on success, < 0 on failure
*/
int
enet_host_compress_with_range_coder (ENetHost * host)
{
ENetCompressor compressor;
memset (& compressor, 0, sizeof (compressor));
compressor.context = enet_range_coder_create();
if (compressor.context == NULL)
return -1;
compressor.compress = enet_range_coder_compress;
compressor.decompress = enet_range_coder_decompress;
compressor.destroy = enet_range_coder_destroy;
enet_host_compress (host, & compressor);
return 0;
}
/** @} */

View File

@ -1,29 +0,0 @@
#ifndef __ENET_CALLBACKS_H__
#define __ENET_CALLBACKS_H__
/**
@file callbacks.h
@brief ENet callbacks
*/
#include <stdlib.h>
typedef struct _ENetCallbacks
{
void * (ENET_CALLBACK * malloc) (size_t size);
void (ENET_CALLBACK * free) (void * memory);
void (ENET_CALLBACK * no_memory) (void);
} ENetCallbacks;
/** @defgroup callbacks ENet internal callbacks
@{
@ingroup private
*/
extern void * enet_malloc (size_t);
extern void enet_free (void *);
/** @} */
#endif /* __ENET_CALLBACKS_H__ */

View File

@ -1,632 +0,0 @@
#ifndef __ENET_ENET_H__
#define __ENET_ENET_H__
/**
@file enet.h
@brief ENet public header file
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include <stdlib.h>
// -- Pandemonium start --
#if 0
#ifdef _WIN32
#include "enet/win32.h"
#else
#include "enet/unix.h"
#endif
#endif
#include "enet/pandemonium.h"
// -- Pandemonium end --
#include "enet/types.h"
#include "enet/protocol.h"
#include "enet/list.h"
#include "enet/callbacks.h"
#define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3
#define ENET_VERSION_PATCH 17
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
#define ENET_VERSION_GET_PATCH(version) ((version)&0xFF)
#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
typedef enet_uint32 ENetVersion;
struct _ENetHost;
struct _ENetEvent;
struct _ENetPacket;
typedef enum _ENetSocketType
{
ENET_SOCKET_TYPE_STREAM = 1,
ENET_SOCKET_TYPE_DATAGRAM = 2
} ENetSocketType;
typedef enum _ENetSocketWait
{
ENET_SOCKET_WAIT_NONE = 0,
ENET_SOCKET_WAIT_SEND = (1 << 0),
ENET_SOCKET_WAIT_RECEIVE = (1 << 1),
ENET_SOCKET_WAIT_INTERRUPT = (1 << 2)
} ENetSocketWait;
typedef enum _ENetSocketOption
{
ENET_SOCKOPT_NONBLOCK = 1,
ENET_SOCKOPT_BROADCAST = 2,
ENET_SOCKOPT_RCVBUF = 3,
ENET_SOCKOPT_SNDBUF = 4,
ENET_SOCKOPT_REUSEADDR = 5,
ENET_SOCKOPT_RCVTIMEO = 6,
ENET_SOCKOPT_SNDTIMEO = 7,
ENET_SOCKOPT_ERROR = 8,
ENET_SOCKOPT_NODELAY = 9,
ENET_SOCKOPT_TTL = 10
} ENetSocketOption;
typedef enum _ENetSocketShutdown
{
ENET_SOCKET_SHUTDOWN_READ = 0,
ENET_SOCKET_SHUTDOWN_WRITE = 1,
ENET_SOCKET_SHUTDOWN_READ_WRITE = 2
} ENetSocketShutdown;
#define ENET_HOST_ANY 0
#define ENET_HOST_BROADCAST 0xFFFFFFFFU
#define ENET_PORT_ANY 0
/**
* Portable internet address structure.
*
* The host must be specified in network byte-order, and the port must be in host
* byte-order. The constant ENET_HOST_ANY may be used to specify the default
* server host. The constant ENET_HOST_BROADCAST may be used to specify the
* broadcast address (255.255.255.255). This makes sense for enet_host_connect,
* but not for enet_host_create. Once a server responds to a broadcast, the
* address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
*/
// -- Pandemonium start --
#if 0
typedef struct _ENetAddress
{
enet_uint32 host;
enet_uint16 port;
} ENetAddress;
#endif
// -- Pandemonium end --
/**
* Packet flag bit constants.
*
* The host must be specified in network byte-order, and the port must be in
* host byte-order. The constant ENET_HOST_ANY may be used to specify the
* default server host.
@sa ENetPacket
*/
typedef enum _ENetPacketFlag
{
/** packet must be received by the target peer and resend attempts should be
* made until the packet is delivered */
ENET_PACKET_FLAG_RELIABLE = (1 << 0),
/** packet will not be sequenced with other packets
* not supported for reliable packets
*/
ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
/** packet will not allocate data, and user must supply it instead */
ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2),
/** packet will be fragmented using unreliable (instead of reliable) sends
* if it exceeds the MTU */
ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3),
/** whether the packet has been sent from all queues it has been entered into */
ENET_PACKET_FLAG_SENT = (1<<8)
} ENetPacketFlag;
typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
/**
* ENet packet structure.
*
* An ENet data packet that may be sent to or received from a peer. The shown
* fields should only be read and never modified. The data field contains the
* allocated data for the packet. The dataLength fields specifies the length
* of the allocated data. The flags field is either 0 (specifying no flags),
* or a bitwise-or of any combination of the following flags:
*
* ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer
* and resend attempts should be made until the packet is delivered
*
* ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets
* (not supported for reliable packets)
*
* ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
*
* ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT - packet will be fragmented using unreliable
* (instead of reliable) sends if it exceeds the MTU
*
* ENET_PACKET_FLAG_SENT - whether the packet has been sent from all queues it has been entered into
@sa ENetPacketFlag
*/
typedef struct _ENetPacket
{
size_t referenceCount; /**< internal use only */
enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */
enet_uint8 * data; /**< allocated data for packet */
size_t dataLength; /**< length of data */
ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */
void * userData; /**< application private data, may be freely modified */
} ENetPacket;
typedef struct _ENetAcknowledgement
{
ENetListNode acknowledgementList;
enet_uint32 sentTime;
ENetProtocol command;
} ENetAcknowledgement;
typedef struct _ENetOutgoingCommand
{
ENetListNode outgoingCommandList;
enet_uint16 reliableSequenceNumber;
enet_uint16 unreliableSequenceNumber;
enet_uint32 sentTime;
enet_uint32 roundTripTimeout;
enet_uint32 queueTime;
enet_uint32 fragmentOffset;
enet_uint16 fragmentLength;
enet_uint16 sendAttempts;
ENetProtocol command;
ENetPacket * packet;
} ENetOutgoingCommand;
typedef struct _ENetIncomingCommand
{
ENetListNode incomingCommandList;
enet_uint16 reliableSequenceNumber;
enet_uint16 unreliableSequenceNumber;
ENetProtocol command;
enet_uint32 fragmentCount;
enet_uint32 fragmentsRemaining;
enet_uint32 * fragments;
ENetPacket * packet;
} ENetIncomingCommand;
typedef enum _ENetPeerState
{
ENET_PEER_STATE_DISCONNECTED = 0,
ENET_PEER_STATE_CONNECTING = 1,
ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2,
ENET_PEER_STATE_CONNECTION_PENDING = 3,
ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4,
ENET_PEER_STATE_CONNECTED = 5,
ENET_PEER_STATE_DISCONNECT_LATER = 6,
ENET_PEER_STATE_DISCONNECTING = 7,
ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8,
ENET_PEER_STATE_ZOMBIE = 9
} ENetPeerState;
#ifndef ENET_BUFFER_MAXIMUM
#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
#endif
enum
{
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
ENET_HOST_DEFAULT_MTU = 1392,
ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024,
ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA = 32 * 1024 * 1024,
ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500,
ENET_PEER_DEFAULT_PACKET_THROTTLE = 32,
ENET_PEER_PACKET_THROTTLE_SCALE = 32,
ENET_PEER_PACKET_THROTTLE_COUNTER = 7,
ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2,
ENET_PEER_PACKET_THROTTLE_DECELERATION = 2,
ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000,
ENET_PEER_PACKET_LOSS_SCALE = (1 << 16),
ENET_PEER_PACKET_LOSS_INTERVAL = 10000,
ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024,
ENET_PEER_TIMEOUT_LIMIT = 32,
ENET_PEER_TIMEOUT_MINIMUM = 5000,
ENET_PEER_TIMEOUT_MAXIMUM = 30000,
ENET_PEER_PING_INTERVAL = 500,
ENET_PEER_UNSEQUENCED_WINDOWS = 64,
ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024,
ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32,
ENET_PEER_RELIABLE_WINDOWS = 16,
ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000,
ENET_PEER_FREE_RELIABLE_WINDOWS = 8
};
typedef struct _ENetChannel
{
enet_uint16 outgoingReliableSequenceNumber;
enet_uint16 outgoingUnreliableSequenceNumber;
enet_uint16 usedReliableWindows;
enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS];
enet_uint16 incomingReliableSequenceNumber;
enet_uint16 incomingUnreliableSequenceNumber;
ENetList incomingReliableCommands;
ENetList incomingUnreliableCommands;
} ENetChannel;
typedef enum _ENetPeerFlag
{
ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0),
ENET_PEER_FLAG_CONTINUE_SENDING = (1 << 1)
} ENetPeerFlag;
/**
* An ENet peer which data packets may be sent or received from.
*
* No fields should be modified unless otherwise specified.
*/
typedef struct _ENetPeer
{
ENetListNode dispatchList;
struct _ENetHost * host;
enet_uint16 outgoingPeerID;
enet_uint16 incomingPeerID;
enet_uint32 connectID;
enet_uint8 outgoingSessionID;
enet_uint8 incomingSessionID;
ENetAddress address; /**< Internet address of the peer */
void * data; /**< Application private data, may be freely modified */
ENetPeerState state;
ENetChannel * channels;
size_t channelCount; /**< Number of channels allocated for communication with peer */
enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */
enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */
enet_uint32 incomingBandwidthThrottleEpoch;
enet_uint32 outgoingBandwidthThrottleEpoch;
enet_uint32 incomingDataTotal;
enet_uint32 outgoingDataTotal;
enet_uint32 lastSendTime;
enet_uint32 lastReceiveTime;
enet_uint32 nextTimeout;
enet_uint32 earliestTimeout;
enet_uint32 packetLossEpoch;
enet_uint32 packetsSent;
enet_uint32 packetsLost;
enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
enet_uint32 packetLossVariance;
enet_uint32 packetThrottle;
enet_uint32 packetThrottleLimit;
enet_uint32 packetThrottleCounter;
enet_uint32 packetThrottleEpoch;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
enet_uint32 packetThrottleInterval;
enet_uint32 pingInterval;
enet_uint32 timeoutLimit;
enet_uint32 timeoutMinimum;
enet_uint32 timeoutMaximum;
enet_uint32 lastRoundTripTime;
enet_uint32 lowestRoundTripTime;
enet_uint32 lastRoundTripTimeVariance;
enet_uint32 highestRoundTripTimeVariance;
enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
enet_uint32 roundTripTimeVariance;
enet_uint32 mtu;
enet_uint32 windowSize;
enet_uint32 reliableDataInTransit;
enet_uint16 outgoingReliableSequenceNumber;
ENetList acknowledgements;
ENetList sentReliableCommands;
ENetList outgoingSendReliableCommands;
ENetList outgoingCommands;
ENetList dispatchedCommands;
enet_uint16 flags;
enet_uint16 reserved;
enet_uint16 incomingUnsequencedGroup;
enet_uint16 outgoingUnsequencedGroup;
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
enet_uint32 eventData;
size_t totalWaitingData;
} ENetPeer;
/** An ENet packet compressor for compressing UDP packets before socket sends or receives.
*/
typedef struct _ENetCompressor
{
/** Context data for the compressor. Must be non-NULL. */
void * context;
/** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit);
/** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit);
/** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */
void (ENET_CALLBACK * destroy) (void * context);
} ENetCompressor;
/** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */
typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount);
/** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */
typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, struct _ENetEvent * event);
/** An ENet host for communicating with peers.
*
* No fields should be modified unless otherwise stated.
@sa enet_host_create()
@sa enet_host_destroy()
@sa enet_host_connect()
@sa enet_host_service()
@sa enet_host_flush()
@sa enet_host_broadcast()
@sa enet_host_compress()
@sa enet_host_compress_with_range_coder()
@sa enet_host_channel_limit()
@sa enet_host_bandwidth_limit()
@sa enet_host_bandwidth_throttle()
*/
typedef struct _ENetHost
{
ENetSocket socket;
ENetAddress address; /**< Internet address of the host */
enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */
enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */
enet_uint32 bandwidthThrottleEpoch;
enet_uint32 mtu;
enet_uint32 randomSeed;
int recalculateBandwidthLimits;
ENetPeer * peers; /**< array of peers allocated for this host */
size_t peerCount; /**< number of peers allocated for this host */
size_t channelLimit; /**< maximum number of channels allowed for connected peers */
enet_uint32 serviceTime;
ENetList dispatchQueue;
enet_uint32 totalQueued;
size_t packetSize;
enet_uint16 headerFlags;
ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
size_t commandCount;
ENetBuffer buffers [ENET_BUFFER_MAXIMUM];
size_t bufferCount;
ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */
ENetCompressor compressor;
enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
ENetAddress receivedAddress;
enet_uint8 * receivedData;
size_t receivedDataLength;
enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */
enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */
enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */
enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */
size_t connectedPeers;
size_t bandwidthLimitedPeers;
size_t duplicatePeers; /**< optional number of allowed peers from duplicate IPs, defaults to ENET_PROTOCOL_MAXIMUM_PEER_ID */
size_t maximumPacketSize; /**< the maximum allowable packet size that may be sent or received on a peer */
size_t maximumWaitingData; /**< the maximum aggregate amount of buffer space a peer may use waiting for packets to be delivered */
} ENetHost;
/**
* An ENet event type, as specified in @ref ENetEvent.
*/
typedef enum _ENetEventType
{
/** no event occurred within the specified time limit */
ENET_EVENT_TYPE_NONE = 0,
/** a connection request initiated by enet_host_connect has completed.
* The peer field contains the peer which successfully connected.
*/
ENET_EVENT_TYPE_CONNECT = 1,
/** a peer has disconnected. This event is generated on a successful
* completion of a disconnect initiated by enet_peer_disconnect, if
* a peer has timed out, or if a connection request intialized by
* enet_host_connect has timed out. The peer field contains the peer
* which disconnected. The data field contains user supplied data
* describing the disconnection, or 0, if none is available.
*/
ENET_EVENT_TYPE_DISCONNECT = 2,
/** a packet has been received from a peer. The peer field specifies the
* peer which sent the packet. The channelID field specifies the channel
* number upon which the packet was received. The packet field contains
* the packet that was received; this packet must be destroyed with
* enet_packet_destroy after use.
*/
ENET_EVENT_TYPE_RECEIVE = 3
} ENetEventType;
/**
* An ENet event as returned by enet_host_service().
@sa enet_host_service
*/
typedef struct _ENetEvent
{
ENetEventType type; /**< type of the event */
ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */
enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */
enet_uint32 data; /**< data associated with the event, if appropriate */
ENetPacket * packet; /**< packet associated with the event, if appropriate */
} ENetEvent;
/** @defgroup global ENet global functions
@{
*/
/**
Initializes ENet globally. Must be called prior to using any functions in
ENet.
@returns 0 on success, < 0 on failure
*/
ENET_API int enet_initialize (void);
/**
Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored.
@param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use
@param inits user-overridden callbacks where any NULL callbacks will use ENet's defaults
@returns 0 on success, < 0 on failure
*/
ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits);
/**
Shuts down ENet globally. Should be called when a program that has
initialized ENet exits.
*/
ENET_API void enet_deinitialize (void);
/**
Gives the linked version of the ENet library.
@returns the version number
*/
ENET_API ENetVersion enet_linked_version (void);
/** @} */
/** @defgroup private ENet private implementation functions */
/**
Returns the wall-time in milliseconds. Its initial value is unspecified
unless otherwise set.
*/
ENET_API enet_uint32 enet_time_get (void);
/**
Sets the current wall-time in milliseconds.
*/
ENET_API void enet_time_set (enet_uint32);
/** @defgroup socket ENet socket functions
@{
*/
ENET_API ENetSocket enet_socket_create (ENetSocketType);
ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
ENET_API int enet_socket_get_address (ENetSocket, ENetAddress *);
ENET_API int enet_socket_listen (ENetSocket, int);
ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
ENET_API int enet_socket_get_option (ENetSocket, ENetSocketOption, int *);
ENET_API int enet_socket_shutdown (ENetSocket, ENetSocketShutdown);
ENET_API void enet_socket_destroy (ENetSocket);
ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
/** @} */
/** @defgroup Address ENet address functions
@{
*/
/** Attempts to parse the printable form of the IP address in the parameter hostName
and sets the host field in the address parameter if successful.
@param address destination to store the parsed IP address
@param hostName IP address to parse
@retval 0 on success
@retval < 0 on failure
@returns the address of the given hostName in address on success
*/
ENET_API int enet_address_set_host_ip (ENetAddress * address, const char * hostName);
/** Attempts to resolve the host named by the parameter hostName and sets
the host field in the address parameter if successful.
@param address destination to store resolved address
@param hostName host name to lookup
@retval 0 on success
@retval < 0 on failure
@returns the address of the given hostName in address on success
*/
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
/** Gives the printable form of the IP address specified in the address parameter.
@param address address printed
@param hostName destination for name, must not be NULL
@param nameLength maximum length of hostName.
@returns the null-terminated name of the host in hostName on success
@retval 0 on success
@retval < 0 on failure
*/
ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
/** Attempts to do a reverse lookup of the host field in the address parameter.
@param address address used for reverse lookup
@param hostName destination for name, must not be NULL
@param nameLength maximum length of hostName.
@returns the null-terminated name of the host in hostName on success
@retval 0 on success
@retval < 0 on failure
*/
ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
/** @} */
ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
ENET_API void enet_packet_destroy (ENetPacket *);
ENET_API int enet_packet_resize (ENetPacket *, size_t);
ENET_API enet_uint32 enet_crc32 (const ENetBuffer *, size_t);
ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
ENET_API void enet_host_destroy (ENetHost *);
ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);
ENET_API int enet_host_check_events (ENetHost *, ENetEvent *);
ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
ENET_API void enet_host_flush (ENetHost *);
ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *);
ENET_API int enet_host_compress_with_range_coder (ENetHost * host);
ENET_API void enet_host_channel_limit (ENetHost *, size_t);
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
extern void enet_host_bandwidth_throttle (ENetHost *);
extern enet_uint32 enet_host_random_seed (void);
extern enet_uint32 enet_host_random (ENetHost *);
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
ENET_API void enet_peer_ping (ENetPeer *);
ENET_API void enet_peer_ping_interval (ENetPeer *, enet_uint32);
ENET_API void enet_peer_timeout (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
ENET_API void enet_peer_reset (ENetPeer *);
ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32);
ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32);
ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32);
ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
extern int enet_peer_throttle (ENetPeer *, enet_uint32);
extern void enet_peer_reset_queues (ENetPeer *);
extern int enet_peer_has_outgoing_commands (ENetPeer *);
extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, const void *, size_t, enet_uint32, enet_uint32);
extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
extern void enet_peer_on_connect (ENetPeer *);
extern void enet_peer_on_disconnect (ENetPeer *);
ENET_API void * enet_range_coder_create (void);
ENET_API void enet_range_coder_destroy (void *);
ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t);
ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t);
extern size_t enet_protocol_command_size (enet_uint8);
// -- Pandemonium start --
#include "enet/pandemonium_ext.h"
// -- Pandemonium end --
#ifdef __cplusplus
}
#endif
#endif /* __ENET_ENET_H__ */

View File

@ -1,45 +0,0 @@
#ifndef __ENET_LIST_H__
#define __ENET_LIST_H__
/**
@file list.h
@brief ENet list management
*/
#include <stdlib.h>
typedef struct _ENetListNode
{
struct _ENetListNode * next;
struct _ENetListNode * previous;
} ENetListNode;
typedef ENetListNode * ENetListIterator;
typedef struct _ENetList
{
ENetListNode sentinel;
} ENetList;
extern void enet_list_clear (ENetList *);
extern ENetListIterator enet_list_insert (ENetListIterator, void *);
extern void * enet_list_remove (ENetListIterator);
extern ENetListIterator enet_list_move (ENetListIterator, void *, void *);
extern size_t enet_list_size (ENetList *);
#define enet_list_begin(list) ((list) -> sentinel.next)
#define enet_list_end(list) (& (list) -> sentinel)
#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
#define enet_list_next(iterator) ((iterator) -> next)
#define enet_list_previous(iterator) ((iterator) -> previous)
#define enet_list_front(list) ((void *) (list) -> sentinel.next)
#define enet_list_back(list) ((void *) (list) -> sentinel.previous)
#endif /* __ENET_LIST_H__ */

View File

@ -1,82 +0,0 @@
#ifndef __ENET_PANDEMONIUM_H__
#define __ENET_PANDEMONIUM_H__
/* pandemonium.h */
/* This file is part of: */
/* PANDEMONIUM ENGINE */
/* https://godotengine.org */
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**
@file pandemonium.h
@brief ENet Pandemonium header
*/
#ifdef WINDOWS_ENABLED
#include <stdint.h>
#include <winsock2.h>
#endif
#ifdef UNIX_ENABLED
#include <arpa/inet.h>
#endif
#ifdef MSG_MAXIOVLEN
#define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN
#endif
typedef void *ENetSocket;
#define ENET_SOCKET_NULL NULL
#define ENET_HOST_TO_NET_16(value) (htons(value)) /**< macro that converts host to net byte-order of a 16-bit value */
#define ENET_HOST_TO_NET_32(value) (htonl(value)) /**< macro that converts host to net byte-order of a 32-bit value */
#define ENET_NET_TO_HOST_16(value) (ntohs(value)) /**< macro that converts net to host byte-order of a 16-bit value */
#define ENET_NET_TO_HOST_32(value) (ntohl(value)) /**< macro that converts net to host byte-order of a 32-bit value */
typedef struct
{
void *data;
size_t dataLength;
} ENetBuffer;
#define ENET_CALLBACK
#define ENET_API extern
typedef void ENetSocketSet;
typedef struct _ENetAddress
{
uint8_t host[16];
uint16_t port;
uint8_t wildcard;
} ENetAddress;
#define enet_host_equal(host_a, host_b) (memcmp(&host_a, &host_b,16) == 0)
#endif /* __ENET_PANDEMONIUM_H__ */

View File

@ -1,18 +0,0 @@
#ifndef __ENET_PANDEMONIUM_EXT_H__
#define __ENET_PANDEMONIUM_EXT_H__
/** Sets the host field in the address parameter from ip struct.
@param address destination to store resolved address
@param ip the ip struct to read from
@param size the size of the ip struct.
@retval 0 on success
@retval != 0 on failure
@returns the address of the given ip in address on success.
*/
ENET_API void enet_address_set_ip(ENetAddress * address, const uint8_t * ip, size_t size);
ENET_API void enet_host_dtls_server_setup (ENetHost *, void *, void *);
ENET_API void enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *);
ENET_API void enet_host_refuse_new_connections (ENetHost *, int);
#endif // __ENET_PANDEMONIUM_EXT_H__

View File

@ -1,200 +0,0 @@
#ifndef __ENET_PROTOCOL_H__
#define __ENET_PROTOCOL_H__
/**
@file protocol.h
@brief ENet protocol
*/
#include "enet/types.h"
enum
{
ENET_PROTOCOL_MINIMUM_MTU = 576,
ENET_PROTOCOL_MAXIMUM_MTU = 4096,
ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 65536,
ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF,
ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024
};
typedef enum _ENetProtocolCommand
{
ENET_PROTOCOL_COMMAND_NONE = 0,
ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1,
ENET_PROTOCOL_COMMAND_CONNECT = 2,
ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3,
ENET_PROTOCOL_COMMAND_DISCONNECT = 4,
ENET_PROTOCOL_COMMAND_PING = 5,
ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12,
ENET_PROTOCOL_COMMAND_COUNT = 13,
ENET_PROTOCOL_COMMAND_MASK = 0x0F
} ENetProtocolCommand;
typedef enum _ENetProtocolFlag
{
ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15),
ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12),
ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12
} ENetProtocolFlag;
#ifdef _MSC_VER
#pragma pack(push, 1)
#define ENET_PACKED
#elif defined(__GNUC__) || defined(__clang__)
#define ENET_PACKED __attribute__ ((packed))
#else
#define ENET_PACKED
#endif
typedef struct _ENetProtocolHeader
{
enet_uint16 peerID;
enet_uint16 sentTime;
} ENET_PACKED ENetProtocolHeader;
typedef struct _ENetProtocolCommandHeader
{
enet_uint8 command;
enet_uint8 channelID;
enet_uint16 reliableSequenceNumber;
} ENET_PACKED ENetProtocolCommandHeader;
typedef struct _ENetProtocolAcknowledge
{
ENetProtocolCommandHeader header;
enet_uint16 receivedReliableSequenceNumber;
enet_uint16 receivedSentTime;
} ENET_PACKED ENetProtocolAcknowledge;
typedef struct _ENetProtocolConnect
{
ENetProtocolCommandHeader header;
enet_uint16 outgoingPeerID;
enet_uint8 incomingSessionID;
enet_uint8 outgoingSessionID;
enet_uint32 mtu;
enet_uint32 windowSize;
enet_uint32 channelCount;
enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth;
enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
enet_uint32 connectID;
enet_uint32 data;
} ENET_PACKED ENetProtocolConnect;
typedef struct _ENetProtocolVerifyConnect
{
ENetProtocolCommandHeader header;
enet_uint16 outgoingPeerID;
enet_uint8 incomingSessionID;
enet_uint8 outgoingSessionID;
enet_uint32 mtu;
enet_uint32 windowSize;
enet_uint32 channelCount;
enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth;
enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
enet_uint32 connectID;
} ENET_PACKED ENetProtocolVerifyConnect;
typedef struct _ENetProtocolBandwidthLimit
{
ENetProtocolCommandHeader header;
enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth;
} ENET_PACKED ENetProtocolBandwidthLimit;
typedef struct _ENetProtocolThrottleConfigure
{
ENetProtocolCommandHeader header;
enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
} ENET_PACKED ENetProtocolThrottleConfigure;
typedef struct _ENetProtocolDisconnect
{
ENetProtocolCommandHeader header;
enet_uint32 data;
} ENET_PACKED ENetProtocolDisconnect;
typedef struct _ENetProtocolPing
{
ENetProtocolCommandHeader header;
} ENET_PACKED ENetProtocolPing;
typedef struct _ENetProtocolSendReliable
{
ENetProtocolCommandHeader header;
enet_uint16 dataLength;
} ENET_PACKED ENetProtocolSendReliable;
typedef struct _ENetProtocolSendUnreliable
{
ENetProtocolCommandHeader header;
enet_uint16 unreliableSequenceNumber;
enet_uint16 dataLength;
} ENET_PACKED ENetProtocolSendUnreliable;
typedef struct _ENetProtocolSendUnsequenced
{
ENetProtocolCommandHeader header;
enet_uint16 unsequencedGroup;
enet_uint16 dataLength;
} ENET_PACKED ENetProtocolSendUnsequenced;
typedef struct _ENetProtocolSendFragment
{
ENetProtocolCommandHeader header;
enet_uint16 startSequenceNumber;
enet_uint16 dataLength;
enet_uint32 fragmentCount;
enet_uint32 fragmentNumber;
enet_uint32 totalLength;
enet_uint32 fragmentOffset;
} ENET_PACKED ENetProtocolSendFragment;
typedef union _ENetProtocol
{
ENetProtocolCommandHeader header;
ENetProtocolAcknowledge acknowledge;
ENetProtocolConnect connect;
ENetProtocolVerifyConnect verifyConnect;
ENetProtocolDisconnect disconnect;
ENetProtocolPing ping;
ENetProtocolSendReliable sendReliable;
ENetProtocolSendUnreliable sendUnreliable;
ENetProtocolSendUnsequenced sendUnsequenced;
ENetProtocolSendFragment sendFragment;
ENetProtocolBandwidthLimit bandwidthLimit;
ENetProtocolThrottleConfigure throttleConfigure;
} ENET_PACKED ENetProtocol;
#ifdef _MSC_VER
#pragma pack(pop)
#endif
#endif /* __ENET_PROTOCOL_H__ */

View File

@ -1,20 +0,0 @@
#ifndef __ENET_TIME_H__
#define __ENET_TIME_H__
/**
@file time.h
@brief ENet time constants and macros
*/
#define ENET_TIME_OVERFLOW 86400000
#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
#endif /* __ENET_TIME_H__ */

View File

@ -1,15 +0,0 @@
#ifndef __ENET_TYPES_H__
#define __ENET_TYPES_H__
/**
@file types.h
@brief type definitions for ENet
*/
typedef unsigned char enet_uint8; /**< unsigned 8-bit type */
typedef unsigned short enet_uint16; /**< unsigned 16-bit type */
typedef unsigned int enet_uint32; /**< unsigned 32-bit type */
#endif /* __ENET_TYPES_H__ */

View File

@ -1,15 +0,0 @@
#ifndef __ENET_UTILITY_H__
#define __ENET_UTILITY_H__
/**
@file utility.h
@brief ENet utility header
*/
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
#define ENET_DIFFERENCE(x, y) ((x) < (y) ? (y) - (x) : (x) - (y))
#endif /* __ENET_UTILITY_H__ */

View File

@ -1,503 +0,0 @@
/**
@file host.c
@brief ENet host management functions
*/
#define ENET_BUILDING_LIB 1
#include <string.h>
#include "enet/enet.h"
/** @defgroup host ENet host functions
@{
*/
/** Creates a host for communicating to peers.
@param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
@param peerCount the maximum number of peers that should be allocated for the host.
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
@param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
@param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
@returns the host on success and NULL on failure
@remarks ENet will strategically drop packets on specific sides of a connection between hosts
to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine
the window size of a connection which limits the amount of reliable packets that may be in transit
at any given time.
*/
ENetHost *
enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
{
ENetHost * host;
ENetPeer * currentPeer;
if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
return NULL;
host = (ENetHost *) enet_malloc (sizeof (ENetHost));
if (host == NULL)
return NULL;
memset (host, 0, sizeof (ENetHost));
host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
if (host -> peers == NULL)
{
enet_free (host);
return NULL;
}
memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
{
if (host -> socket != ENET_SOCKET_NULL)
enet_socket_destroy (host -> socket);
enet_free (host -> peers);
enet_free (host);
return NULL;
}
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0)
host -> address = * address;
if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
else
if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
host -> randomSeed = (enet_uint32) (size_t) host;
host -> randomSeed += enet_host_random_seed ();
host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
host -> channelLimit = channelLimit;
host -> incomingBandwidth = incomingBandwidth;
host -> outgoingBandwidth = outgoingBandwidth;
host -> bandwidthThrottleEpoch = 0;
host -> recalculateBandwidthLimits = 0;
host -> mtu = ENET_HOST_DEFAULT_MTU;
host -> peerCount = peerCount;
host -> commandCount = 0;
host -> bufferCount = 0;
host -> checksum = NULL;
memset(host -> receivedAddress.host, 0, 16);
host -> receivedAddress.port = 0;
host -> receivedData = NULL;
host -> receivedDataLength = 0;
host -> totalSentData = 0;
host -> totalSentPackets = 0;
host -> totalReceivedData = 0;
host -> totalReceivedPackets = 0;
host -> totalQueued = 0;
host -> connectedPeers = 0;
host -> bandwidthLimitedPeers = 0;
host -> duplicatePeers = ENET_PROTOCOL_MAXIMUM_PEER_ID;
host -> maximumPacketSize = ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE;
host -> maximumWaitingData = ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA;
host -> compressor.context = NULL;
host -> compressor.compress = NULL;
host -> compressor.decompress = NULL;
host -> compressor.destroy = NULL;
host -> intercept = NULL;
enet_list_clear (& host -> dispatchQueue);
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
currentPeer -> host = host;
currentPeer -> incomingPeerID = currentPeer - host -> peers;
currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF;
currentPeer -> data = NULL;
enet_list_clear (& currentPeer -> acknowledgements);
enet_list_clear (& currentPeer -> sentReliableCommands);
enet_list_clear (& currentPeer -> outgoingCommands);
enet_list_clear (& currentPeer -> outgoingSendReliableCommands);
enet_list_clear (& currentPeer -> dispatchedCommands);
enet_peer_reset (currentPeer);
}
return host;
}
/** Destroys the host and all resources associated with it.
@param host pointer to the host to destroy
*/
void
enet_host_destroy (ENetHost * host)
{
ENetPeer * currentPeer;
if (host == NULL)
return;
enet_socket_destroy (host -> socket);
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
enet_peer_reset (currentPeer);
}
if (host -> compressor.context != NULL && host -> compressor.destroy)
(* host -> compressor.destroy) (host -> compressor.context);
enet_free (host -> peers);
enet_free (host);
}
enet_uint32
enet_host_random (ENetHost * host)
{
/* Mulberry32 by Tommy Ettinger */
enet_uint32 n = (host -> randomSeed += 0x6D2B79F5U);
n = (n ^ (n >> 15)) * (n | 1U);
n ^= n + (n ^ (n >> 7)) * (n | 61U);
return n ^ (n >> 14);
}
/** Initiates a connection to a foreign host.
@param host host seeking the connection
@param address destination for the connection
@param channelCount number of channels to allocate
@param data user data supplied to the receiving host
@returns a peer representing the foreign host on success, NULL on failure
@remarks The peer returned will have not completed the connection until enet_host_service()
notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
*/
ENetPeer *
enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data)
{
ENetPeer * currentPeer;
ENetChannel * channel;
ENetProtocol command;
if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
else
if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
break;
}
if (currentPeer >= & host -> peers [host -> peerCount])
return NULL;
currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
if (currentPeer -> channels == NULL)
return NULL;
currentPeer -> channelCount = channelCount;
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
currentPeer -> address = * address;
currentPeer -> connectID = enet_host_random (host);
currentPeer -> mtu = host -> mtu;
if (host -> outgoingBandwidth == 0)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
else
currentPeer -> windowSize = (host -> outgoingBandwidth /
ENET_PEER_WINDOW_SIZE_SCALE) *
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
else
if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
for (channel = currentPeer -> channels;
channel < & currentPeer -> channels [channelCount];
++ channel)
{
channel -> outgoingReliableSequenceNumber = 0;
channel -> outgoingUnreliableSequenceNumber = 0;
channel -> incomingReliableSequenceNumber = 0;
channel -> incomingUnreliableSequenceNumber = 0;
enet_list_clear (& channel -> incomingReliableCommands);
enet_list_clear (& channel -> incomingUnreliableCommands);
channel -> usedReliableWindows = 0;
memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
}
command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
command.connect.incomingSessionID = currentPeer -> incomingSessionID;
command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
command.connect.connectID = currentPeer -> connectID;
command.connect.data = ENET_HOST_TO_NET_32 (data);
enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
return currentPeer;
}
/** Queues a packet to be sent to all peers associated with the host.
@param host host on which to broadcast the packet
@param channelID channel on which to broadcast
@param packet packet to broadcast
*/
void
enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
{
ENetPeer * currentPeer;
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
continue;
enet_peer_send (currentPeer, channelID, packet);
}
if (packet -> referenceCount == 0)
enet_packet_destroy (packet);
}
/** Sets the packet compressor the host should use to compress and decompress packets.
@param host host to enable or disable compression for
@param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
*/
void
enet_host_compress (ENetHost * host, const ENetCompressor * compressor)
{
if (host -> compressor.context != NULL && host -> compressor.destroy)
(* host -> compressor.destroy) (host -> compressor.context);
if (compressor)
host -> compressor = * compressor;
else
host -> compressor.context = NULL;
}
/** Limits the maximum allowed channels of future incoming connections.
@param host host to limit
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
*/
void
enet_host_channel_limit (ENetHost * host, size_t channelLimit)
{
if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
else
if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
host -> channelLimit = channelLimit;
}
/** Adjusts the bandwidth limits of a host.
@param host host to adjust
@param incomingBandwidth new incoming bandwidth
@param outgoingBandwidth new outgoing bandwidth
@remarks the incoming and outgoing bandwidth parameters are identical in function to those
specified in enet_host_create().
*/
void
enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
{
host -> incomingBandwidth = incomingBandwidth;
host -> outgoingBandwidth = outgoingBandwidth;
host -> recalculateBandwidthLimits = 1;
}
void
enet_host_bandwidth_throttle (ENetHost * host)
{
enet_uint32 timeCurrent = enet_time_get (),
elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
peersRemaining = (enet_uint32) host -> connectedPeers,
dataTotal = ~0,
bandwidth = ~0,
throttle = 0,
bandwidthLimit = 0;
int needsAdjustment = host -> bandwidthLimitedPeers > 0 ? 1 : 0;
ENetPeer * peer;
ENetProtocol command;
if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
return;
host -> bandwidthThrottleEpoch = timeCurrent;
if (peersRemaining == 0)
return;
if (host -> outgoingBandwidth != 0)
{
dataTotal = 0;
bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
dataTotal += peer -> outgoingDataTotal;
}
}
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
if (dataTotal <= bandwidth)
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
else
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
enet_uint32 peerBandwidth;
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> incomingBandwidth == 0 ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
continue;
peer -> packetThrottleLimit = (peerBandwidth *
ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
if (peer -> packetThrottleLimit == 0)
peer -> packetThrottleLimit = 1;
if (peer -> packetThrottle > peer -> packetThrottleLimit)
peer -> packetThrottle = peer -> packetThrottleLimit;
peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
peer -> incomingDataTotal = 0;
peer -> outgoingDataTotal = 0;
needsAdjustment = 1;
-- peersRemaining;
bandwidth -= peerBandwidth;
dataTotal -= peerBandwidth;
}
}
if (peersRemaining > 0)
{
if (dataTotal <= bandwidth)
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
else
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
peer -> packetThrottleLimit = throttle;
if (peer -> packetThrottle > peer -> packetThrottleLimit)
peer -> packetThrottle = peer -> packetThrottleLimit;
peer -> incomingDataTotal = 0;
peer -> outgoingDataTotal = 0;
}
}
if (host -> recalculateBandwidthLimits)
{
host -> recalculateBandwidthLimits = 0;
peersRemaining = (enet_uint32) host -> connectedPeers;
bandwidth = host -> incomingBandwidth;
needsAdjustment = 1;
if (bandwidth == 0)
bandwidthLimit = 0;
else
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
bandwidthLimit = bandwidth / peersRemaining;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> incomingBandwidthThrottleEpoch == timeCurrent)
continue;
if (peer -> outgoingBandwidth > 0 &&
peer -> outgoingBandwidth >= bandwidthLimit)
continue;
peer -> incomingBandwidthThrottleEpoch = timeCurrent;
needsAdjustment = 1;
-- peersRemaining;
bandwidth -= peer -> outgoingBandwidth;
}
}
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
else
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
}
}
}
/** @} */

View File

@ -1,75 +0,0 @@
/**
@file list.c
@brief ENet linked list functions
*/
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
/**
@defgroup list ENet linked list utility functions
@ingroup private
@{
*/
void
enet_list_clear (ENetList * list)
{
list -> sentinel.next = & list -> sentinel;
list -> sentinel.previous = & list -> sentinel;
}
ENetListIterator
enet_list_insert (ENetListIterator position, void * data)
{
ENetListIterator result = (ENetListIterator) data;
result -> previous = position -> previous;
result -> next = position;
result -> previous -> next = result;
position -> previous = result;
return result;
}
void *
enet_list_remove (ENetListIterator position)
{
position -> previous -> next = position -> next;
position -> next -> previous = position -> previous;
return position;
}
ENetListIterator
enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast)
{
ENetListIterator first = (ENetListIterator) dataFirst,
last = (ENetListIterator) dataLast;
first -> previous -> next = last -> next;
last -> next -> previous = first -> previous;
first -> previous = position -> previous;
last -> next = position;
first -> previous -> next = first;
position -> previous = last;
return first;
}
size_t
enet_list_size (ENetList * list)
{
size_t size = 0;
ENetListIterator position;
for (position = enet_list_begin (list);
position != enet_list_end (list);
position = enet_list_next (position))
++ size;
return size;
}
/** @} */

View File

@ -1,158 +0,0 @@
/**
@file packet.c
@brief ENet packet management functions
*/
#include <string.h>
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
/** @defgroup Packet ENet packet functions
@{
*/
/** Creates a packet that may be sent to a peer.
@param data initial contents of the packet's data; the packet's data will remain uninitialized if data is NULL.
@param dataLength size of the data allocated for this packet
@param flags flags for this packet as described for the ENetPacket structure.
@returns the packet on success, NULL on failure
*/
ENetPacket *
enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
{
ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
if (packet == NULL)
return NULL;
if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
packet -> data = (enet_uint8 *) data;
else
if (dataLength <= 0)
packet -> data = NULL;
else
{
packet -> data = (enet_uint8 *) enet_malloc (dataLength);
if (packet -> data == NULL)
{
enet_free (packet);
return NULL;
}
if (data != NULL)
memcpy (packet -> data, data, dataLength);
}
packet -> referenceCount = 0;
packet -> flags = flags;
packet -> dataLength = dataLength;
packet -> freeCallback = NULL;
packet -> userData = NULL;
return packet;
}
/** Destroys the packet and deallocates its data.
@param packet packet to be destroyed
*/
void
enet_packet_destroy (ENetPacket * packet)
{
if (packet == NULL)
return;
if (packet -> freeCallback != NULL)
(* packet -> freeCallback) (packet);
if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) &&
packet -> data != NULL)
enet_free (packet -> data);
enet_free (packet);
}
/** Attempts to resize the data in the packet to length specified in the
dataLength parameter
@param packet packet to resize
@param dataLength new size for the packet data
@returns 0 on success, < 0 on failure
*/
int
enet_packet_resize (ENetPacket * packet, size_t dataLength)
{
enet_uint8 * newData;
if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
{
packet -> dataLength = dataLength;
return 0;
}
newData = (enet_uint8 *) enet_malloc (dataLength);
if (newData == NULL)
return -1;
memcpy (newData, packet -> data, packet -> dataLength);
enet_free (packet -> data);
packet -> data = newData;
packet -> dataLength = dataLength;
return 0;
}
static const enet_uint32 crcTable [256] =
{
0, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x5005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0xBDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
enet_uint32
enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
{
enet_uint32 crc = 0xFFFFFFFF;
while (bufferCount -- > 0)
{
const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
* dataEnd = & data [buffers -> dataLength];
while (data < dataEnd)
{
crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];
}
++ buffers;
}
return ENET_HOST_TO_NET_32 (~ crc);
}
/** @} */

View File

@ -1,535 +0,0 @@
/* pandemonium.cpp */
/**
@file pandemonium.cpp
@brief ENet Pandemonium specific functions
*/
#include "core/io/dtls_server.h"
#include "core/io/ip.h"
#include "core/io/net_socket.h"
#include "core/io/packet_peer_dtls.h"
#include "core/io/udp_server.h"
#include "core/os/os.h"
// This must be last for windows to compile (tested with MinGW)
#include "enet/enet.h"
/// Abstract ENet interface for UDP/DTLS.
class ENetPandemoniumSocket {
public:
virtual Error bind(IP_Address p_ip, uint16_t p_port) = 0;
virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) = 0;
virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) = 0;
virtual int set_option(ENetSocketOption p_option, int p_value) = 0;
virtual void close() = 0;
virtual void set_refuse_new_connections(bool p_refuse) { /* Only used by dtls server */ }
virtual ~ENetPandemoniumSocket(){};
};
class ENetDTLSClient;
class ENetDTLSServer;
/// NetSocket interface
class ENetUDP : public ENetPandemoniumSocket {
friend class ENetDTLSClient;
friend class ENetDTLSServer;
private:
Ref<NetSocket> sock;
IP_Address address;
uint16_t port;
bool bound;
public:
ENetUDP() {
sock = Ref<NetSocket>(NetSocket::create());
IP::Type ip_type = IP::TYPE_ANY;
bound = false;
sock->open(NetSocket::TYPE_UDP, ip_type);
}
~ENetUDP() {
sock->close();
}
Error bind(IP_Address p_ip, uint16_t p_port) {
address = p_ip;
port = p_port;
bound = true;
return sock->bind(address, port);
}
Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) {
return sock->sendto(p_buffer, p_len, r_sent, p_ip, p_port);
}
Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) {
Error err = sock->poll(NetSocket::POLL_TYPE_IN, 0);
if (err != OK) {
return err;
}
return sock->recvfrom(p_buffer, p_len, r_read, r_ip, r_port);
}
int set_option(ENetSocketOption p_option, int p_value) {
switch (p_option) {
case ENET_SOCKOPT_NONBLOCK: {
sock->set_blocking_enabled(p_value ? false : true);
return 0;
} break;
case ENET_SOCKOPT_BROADCAST: {
sock->set_broadcasting_enabled(p_value ? true : false);
return 0;
} break;
case ENET_SOCKOPT_REUSEADDR: {
sock->set_reuse_address_enabled(p_value ? true : false);
return 0;
} break;
case ENET_SOCKOPT_RCVBUF: {
return -1;
} break;
case ENET_SOCKOPT_SNDBUF: {
return -1;
} break;
case ENET_SOCKOPT_RCVTIMEO: {
return -1;
} break;
case ENET_SOCKOPT_SNDTIMEO: {
return -1;
} break;
case ENET_SOCKOPT_NODELAY: {
sock->set_tcp_no_delay_enabled(p_value ? true : false);
return 0;
} break;
}
return -1;
}
void close() {
sock->close();
}
};
/// DTLS Client ENet interface
class ENetDTLSClient : public ENetPandemoniumSocket {
bool connected;
Ref<PacketPeerUDP> udp;
Ref<PacketPeerDTLS> dtls;
bool verify;
String for_hostname;
Ref<X509Certificate> cert;
public:
ENetDTLSClient(ENetUDP *p_base, Ref<X509Certificate> p_cert, bool p_verify, String p_for_hostname) {
verify = p_verify;
for_hostname = p_for_hostname;
cert = p_cert;
udp.instance();
dtls = Ref<PacketPeerDTLS>(PacketPeerDTLS::create());
p_base->close();
if (p_base->bound) {
bind(p_base->address, p_base->port);
}
connected = false;
}
~ENetDTLSClient() {
close();
}
Error bind(IP_Address p_ip, uint16_t p_port) {
return udp->listen(p_port, p_ip);
}
Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) {
if (!connected) {
udp->connect_to_host(p_ip, p_port);
dtls->connect_to_peer(udp, verify, for_hostname, cert);
connected = true;
}
dtls->poll();
if (dtls->get_status() == PacketPeerDTLS::STATUS_HANDSHAKING) {
return ERR_BUSY;
} else if (dtls->get_status() != PacketPeerDTLS::STATUS_CONNECTED) {
return FAILED;
}
r_sent = p_len;
return dtls->put_packet(p_buffer, p_len);
}
Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) {
dtls->poll();
if (dtls->get_status() == PacketPeerDTLS::STATUS_HANDSHAKING) {
return ERR_BUSY;
}
if (dtls->get_status() != PacketPeerDTLS::STATUS_CONNECTED) {
return FAILED;
}
int pc = dtls->get_available_packet_count();
if (pc == 0) {
return ERR_BUSY;
} else if (pc < 0) {
return FAILED;
}
const uint8_t *buffer;
Error err = dtls->get_packet(&buffer, r_read);
ERR_FAIL_COND_V(err != OK, err);
ERR_FAIL_COND_V(p_len < r_read, ERR_OUT_OF_MEMORY);
memcpy(p_buffer, buffer, r_read);
r_ip = udp->get_packet_address();
r_port = udp->get_packet_port();
return err;
}
int set_option(ENetSocketOption p_option, int p_value) {
return -1;
}
void close() {
dtls->disconnect_from_peer();
udp->close();
}
};
/// DTLSServer - ENet interface
class ENetDTLSServer : public ENetPandemoniumSocket {
Ref<DTLSServer> server;
Ref<UDPServer> udp_server;
RBMap<String, Ref<PacketPeerDTLS> > peers;
int last_service;
public:
ENetDTLSServer(ENetUDP *p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert) {
last_service = 0;
udp_server.instance();
p_base->close();
if (p_base->bound) {
bind(p_base->address, p_base->port);
}
server = Ref<DTLSServer>(DTLSServer::create());
server->setup(p_key, p_cert);
}
~ENetDTLSServer() {
close();
}
void set_refuse_new_connections(bool p_refuse) {
udp_server->set_max_pending_connections(p_refuse ? 0 : 16);
}
Error bind(IP_Address p_ip, uint16_t p_port) {
return udp_server->listen(p_port, p_ip);
}
Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) {
String key = String(p_ip) + ":" + itos(p_port);
ERR_FAIL_COND_V(!peers.has(key), ERR_UNAVAILABLE);
Ref<PacketPeerDTLS> peer = peers[key];
Error err = peer->put_packet(p_buffer, p_len);
if (err == OK) {
r_sent = p_len;
} else if (err == ERR_BUSY) {
r_sent = 0;
} else {
r_sent = -1;
}
return err;
}
Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) {
udp_server->poll();
// TODO limits? Maybe we can better enforce allowed connections!
if (udp_server->is_connection_available()) {
Ref<PacketPeerUDP> udp = udp_server->take_connection();
IP_Address peer_ip = udp->get_packet_address();
int peer_port = udp->get_packet_port();
Ref<PacketPeerDTLS> peer = server->take_connection(udp);
PacketPeerDTLS::Status status = peer->get_status();
if (status == PacketPeerDTLS::STATUS_HANDSHAKING || status == PacketPeerDTLS::STATUS_CONNECTED) {
String key = String(peer_ip) + ":" + itos(peer_port);
peers[key] = peer;
}
}
List<String> remove;
Error err = ERR_BUSY;
// TODO this needs to be fair!
for (RBMap<String, Ref<PacketPeerDTLS> >::Element *E = peers.front(); E; E = E->next()) {
Ref<PacketPeerDTLS> peer = E->get();
peer->poll();
if (peer->get_status() == PacketPeerDTLS::STATUS_HANDSHAKING) {
continue;
} else if (peer->get_status() != PacketPeerDTLS::STATUS_CONNECTED) {
// Peer disconnected, removing it.
remove.push_back(E->key());
continue;
}
if (peer->get_available_packet_count() > 0) {
const uint8_t *buffer;
err = peer->get_packet(&buffer, r_read);
if (err != OK || p_len < r_read) {
// Something wrong with this peer, removing it.
remove.push_back(E->key());
err = FAILED;
continue;
}
Vector<String> s = E->key().rsplit(":", false, 1);
ERR_CONTINUE(s.size() != 2); // BUG!
memcpy(p_buffer, buffer, r_read);
r_ip = s[0];
r_port = s[1].to_int();
break; // err = OK
}
}
// Remove disconnected peers from map.
for (List<String>::Element *E = remove.front(); E; E = E->next()) {
peers.erase(E->get());
}
return err; // OK, ERR_BUSY, or possibly an error.
}
int set_option(ENetSocketOption p_option, int p_value) {
return -1;
}
void close() {
for (RBMap<String, Ref<PacketPeerDTLS> >::Element *E = peers.front(); E; E = E->next()) {
E->get()->disconnect_from_peer();
}
peers.clear();
udp_server->stop();
server->stop();
}
};
static enet_uint32 timeBase = 0;
int enet_initialize(void) {
return 0;
}
void enet_deinitialize(void) {
}
enet_uint32 enet_host_random_seed(void) {
return (enet_uint32)OS::get_singleton()->get_unix_time();
}
enet_uint32 enet_time_get(void) {
return OS::get_singleton()->get_ticks_msec() - timeBase;
}
void enet_time_set(enet_uint32 newTimeBase) {
timeBase = OS::get_singleton()->get_ticks_msec() - newTimeBase;
}
int enet_address_set_host(ENetAddress *address, const char *name) {
IP_Address ip = IP::get_singleton()->resolve_hostname(name);
ERR_FAIL_COND_V(!ip.is_valid(), -1);
enet_address_set_ip(address, ip.get_ipv6(), 16);
return 0;
}
void enet_address_set_ip(ENetAddress *address, const uint8_t *ip, size_t size) {
int len = size > 16 ? 16 : size;
memset(address->host, 0, 16);
memcpy(address->host, ip, len);
}
int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) {
return -1;
}
int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLength) {
return -1;
}
ENetSocket enet_socket_create(ENetSocketType type) {
ENetUDP *socket = memnew(ENetUDP);
return socket;
}
void enet_host_dtls_server_setup(ENetHost *host, void *p_key, void *p_cert) {
ENetUDP *sock = (ENetUDP *)host->socket;
host->socket = memnew(ENetDTLSServer(sock, Ref<CryptoKey>((CryptoKey *)p_key), Ref<X509Certificate>((X509Certificate *)p_cert)));
memdelete(sock);
}
void enet_host_dtls_client_setup(ENetHost *host, void *p_cert, uint8_t p_verify, const char *p_for_hostname) {
ENetUDP *sock = (ENetUDP *)host->socket;
host->socket = memnew(ENetDTLSClient(sock, Ref<X509Certificate>((X509Certificate *)p_cert), p_verify, String(p_for_hostname)));
memdelete(sock);
}
void enet_host_refuse_new_connections(ENetHost *host, int p_refuse) {
ERR_FAIL_COND(!host->socket);
((ENetPandemoniumSocket *)host->socket)->set_refuse_new_connections(p_refuse);
}
int enet_socket_bind(ENetSocket socket, const ENetAddress *address) {
IP_Address ip;
if (address->wildcard) {
ip = IP_Address("*");
} else {
ip.set_ipv6(address->host);
}
ENetPandemoniumSocket *sock = (ENetPandemoniumSocket *)socket;
if (sock->bind(ip, address->port) != OK) {
return -1;
}
return 0;
}
void enet_socket_destroy(ENetSocket socket) {
ENetPandemoniumSocket *sock = (ENetPandemoniumSocket *)socket;
sock->close();
memdelete(sock);
}
int enet_socket_send(ENetSocket socket, const ENetAddress *address, const ENetBuffer *buffers, size_t bufferCount) {
ERR_FAIL_COND_V(address == nullptr, -1);
ENetPandemoniumSocket *sock = (ENetPandemoniumSocket *)socket;
IP_Address dest;
Error err;
size_t i = 0;
dest.set_ipv6(address->host);
// Create a single packet.
PoolVector<uint8_t> out;
PoolVector<uint8_t>::Write w;
int size = 0;
int pos = 0;
for (i = 0; i < bufferCount; i++) {
size += buffers[i].dataLength;
}
out.resize(size);
w = out.write();
for (i = 0; i < bufferCount; i++) {
memcpy(&w[pos], buffers[i].data, buffers[i].dataLength);
pos += buffers[i].dataLength;
}
int sent = 0;
err = sock->sendto((const uint8_t *)&w[0], size, sent, dest, address->port);
if (err != OK) {
if (err == ERR_BUSY) { // Blocking call
return 0;
}
WARN_PRINT("Sending failed!");
return -1;
}
return sent;
}
int enet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount) {
ERR_FAIL_COND_V(bufferCount != 1, -1);
ENetPandemoniumSocket *sock = (ENetPandemoniumSocket *)socket;
int read;
IP_Address ip;
Error err = sock->recvfrom((uint8_t *)buffers[0].data, buffers[0].dataLength, read, ip, address->port);
if (err == ERR_BUSY) {
return 0;
}
if (err != OK) {
return -1;
}
enet_address_set_ip(address, ip.get_ipv6(), 16);
return read;
}
// Not implemented
int enet_socket_wait(ENetSocket socket, enet_uint32 *condition, enet_uint32 timeout) {
return 0; // do we need this function?
}
int enet_socket_get_address(ENetSocket socket, ENetAddress *address) {
return -1; // do we need this function?
}
int enet_socketset_select(ENetSocket maxSocket, ENetSocketSet *readSet, ENetSocketSet *writeSet, enet_uint32 timeout) {
return -1;
}
int enet_socket_listen(ENetSocket socket, int backlog) {
return -1;
}
int enet_socket_set_option(ENetSocket socket, ENetSocketOption option, int value) {
ENetPandemoniumSocket *sock = (ENetPandemoniumSocket *)socket;
return sock->set_option(option, value);
}
int enet_socket_get_option(ENetSocket socket, ENetSocketOption option, int *value) {
return -1;
}
int enet_socket_connect(ENetSocket socket, const ENetAddress *address) {
return -1;
}
ENetSocket enet_socket_accept(ENetSocket socket, ENetAddress *address) {
return nullptr;
}
int enet_socket_shutdown(ENetSocket socket, ENetSocketShutdown how) {
return -1;
}

View File

@ -1,98 +0,0 @@
diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
index fc45cbd0c9..77f8004b80 100644
--- a/thirdparty/enet/enet/enet.h
+++ b/thirdparty/enet/enet/enet.h
@@ -10,13 +10,19 @@ extern "C"
{
#endif
+#include <stdint.h>
#include <stdlib.h>
+// -- Pandemonium start --
+#if 0
#ifdef _WIN32
#include "enet/win32.h"
#else
#include "enet/unix.h"
#endif
+#endif
+#include "enet/pandemonium.h"
+// -- Pandemonium end --
#include "enet/types.h"
#include "enet/protocol.h"
@@ -86,11 +92,15 @@ typedef enum _ENetSocketShutdown
* but not for enet_host_create. Once a server responds to a broadcast, the
* address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
*/
+// -- Pandemonium start --
+#if 0
typedef struct _ENetAddress
{
enet_uint32 host;
enet_uint16 port;
} ENetAddress;
+#endif
+// -- Pandemonium end --
/**
* Packet flag bit constants.
@@ -604,6 +614,10 @@ ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t,
extern size_t enet_protocol_command_size (enet_uint8);
+// -- Pandemonium start --
+#include "enet/pandemonium_ext.h"
+// -- Pandemonium end --
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/enet/host.c b/thirdparty/enet/host.c
index 3b2180f7fd..21ab27e247 100644
--- a/thirdparty/enet/host.c
+++ b/thirdparty/enet/host.c
@@ -87,7 +87,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
host -> commandCount = 0;
host -> bufferCount = 0;
host -> checksum = NULL;
- host -> receivedAddress.host = ENET_HOST_ANY;
+ memset(host -> receivedAddress.host, 0, 16);
host -> receivedAddress.port = 0;
host -> receivedData = NULL;
host -> receivedDataLength = 0;
diff --git a/thirdparty/enet/protocol.c b/thirdparty/enet/protocol.c
index 9d654f1d96..d7fe80f117 100644
--- a/thirdparty/enet/protocol.c
+++ b/thirdparty/enet/protocol.c
@@ -309,7 +309,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
}
else
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
- currentPeer -> address.host == host -> receivedAddress.host)
+ enet_host_equal(currentPeer -> address.host, host -> receivedAddress.host))
{
if (currentPeer -> address.port == host -> receivedAddress.port &&
currentPeer -> connectID == command -> connect.connectID)
@@ -1031,9 +1031,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
- ((host -> receivedAddress.host != peer -> address.host ||
- host -> receivedAddress.port != peer -> address.port) &&
- peer -> address.host != ENET_HOST_BROADCAST) ||
+ (!enet_host_equal(host -> receivedAddress.host, peer -> address.host) ||
+ host -> receivedAddress.port != peer -> address.port) ||
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
sessionID != peer -> incomingSessionID))
return 0;
@@ -1075,7 +1074,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer != NULL)
{
- peer -> address.host = host -> receivedAddress.host;
+ enet_address_set_ip(&(peer -> address), host -> receivedAddress.host, 16);
peer -> address.port = host -> receivedAddress.port;
peer -> incomingDataTotal += host -> receivedDataLength;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,851 +0,0 @@
/* networked_multiplayer_enet.cpp */
/* This file is part of: */
/* PANDEMONIUM ENGINE */
/* https://godotengine.org */
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "networked_multiplayer_enet.h"
#include "core/io/ip.h"
#include "core/io/marshalls.h"
#include "core/os/os.h"
void NetworkedMultiplayerENet::set_transfer_mode(TransferMode p_mode) {
transfer_mode = p_mode;
}
NetworkedMultiplayerPeer::TransferMode NetworkedMultiplayerENet::get_transfer_mode() const {
return transfer_mode;
}
void NetworkedMultiplayerENet::set_target_peer(int p_peer) {
target_peer = p_peer;
}
int NetworkedMultiplayerENet::get_packet_peer() const {
ERR_FAIL_COND_V_MSG(!active, 1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, 1);
return incoming_packets.front()->get().from;
}
int NetworkedMultiplayerENet::get_packet_channel() const {
ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, -1);
return incoming_packets.front()->get().channel;
}
int NetworkedMultiplayerENet::get_last_packet_channel() const {
ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(!current_packet.packet, -1);
return current_packet.channel;
}
Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int p_in_bandwidth, int p_out_bandwidth) {
ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The port number must be set between 0 and 65535 (inclusive).");
ERR_FAIL_COND_V_MSG(p_max_clients < 1 || p_max_clients > 4095, ERR_INVALID_PARAMETER, "The number of clients must be set between 1 and 4095 (inclusive).");
ERR_FAIL_COND_V_MSG(p_in_bandwidth < 0, ERR_INVALID_PARAMETER, "The incoming bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
ERR_FAIL_COND_V_MSG(p_out_bandwidth < 0, ERR_INVALID_PARAMETER, "The outgoing bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
ERR_FAIL_COND_V(dtls_enabled && (dtls_key.is_null() || dtls_cert.is_null()), ERR_INVALID_PARAMETER);
ENetAddress address;
memset(&address, 0, sizeof(address));
#ifdef PANDEMONIUM_ENET
if (bind_ip.is_wildcard()) {
address.wildcard = 1;
} else {
enet_address_set_ip(&address, bind_ip.get_ipv6(), 16);
}
#else
if (bind_ip.is_wildcard()) {
address.host = 0;
} else {
ERR_FAIL_COND_V(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER);
address.host = *(uint32_t *)bind_ip.get_ipv4();
}
#endif
address.port = p_port;
host = enet_host_create(&address /* the address to bind the server host to */,
p_max_clients /* allow up to 32 clients and/or outgoing connections */,
channel_count /* allow up to channel_count to be used */,
p_in_bandwidth /* limit incoming bandwidth if > 0 */,
p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
ERR_FAIL_COND_V_MSG(!host, ERR_CANT_CREATE, "Couldn't create an ENet multiplayer server.");
#ifdef PANDEMONIUM_ENET
if (dtls_enabled) {
enet_host_dtls_server_setup(host, dtls_key.ptr(), dtls_cert.ptr());
}
enet_host_refuse_new_connections(host, refuse_connections);
#endif
active = true;
server = true;
refuse_connections = false;
unique_id = 1;
connection_status = CONNECTION_CONNECTED;
return OK;
}
Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_port, int p_in_bandwidth, int p_out_bandwidth, int p_client_port) {
ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The server port number must be set between 0 and 65535 (inclusive).");
ERR_FAIL_COND_V_MSG(p_client_port < 0 || p_client_port > 65535, ERR_INVALID_PARAMETER, "The client port number must be set between 0 and 65535 (inclusive).");
ERR_FAIL_COND_V_MSG(p_in_bandwidth < 0, ERR_INVALID_PARAMETER, "The incoming bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
ERR_FAIL_COND_V_MSG(p_out_bandwidth < 0, ERR_INVALID_PARAMETER, "The outgoing bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
if (p_client_port != 0) {
ENetAddress c_client;
#ifdef PANDEMONIUM_ENET
if (bind_ip.is_wildcard()) {
c_client.wildcard = 1;
} else {
enet_address_set_ip(&c_client, bind_ip.get_ipv6(), 16);
}
#else
if (bind_ip.is_wildcard()) {
c_client.host = 0;
} else {
ERR_FAIL_COND_V_MSG(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER, "Wildcard IP addresses are only permitted in IPv4, not IPv6.");
c_client.host = *(uint32_t *)bind_ip.get_ipv4();
}
#endif
c_client.port = p_client_port;
host = enet_host_create(&c_client /* create a client host */,
1 /* only allow 1 outgoing connection */,
channel_count /* allow up to channel_count to be used */,
p_in_bandwidth /* limit incoming bandwidth if > 0 */,
p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
} else {
host = enet_host_create(nullptr /* create a client host */,
1 /* only allow 1 outgoing connection */,
channel_count /* allow up to channel_count to be used */,
p_in_bandwidth /* limit incoming bandwidth if > 0 */,
p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
}
ERR_FAIL_COND_V_MSG(!host, ERR_CANT_CREATE, "Couldn't create the ENet client host.");
#ifdef PANDEMONIUM_ENET
if (dtls_enabled) {
enet_host_dtls_client_setup(host, dtls_cert.ptr(), dtls_verify, dtls_hostname.empty() ? p_address.utf8().get_data() : dtls_hostname.utf8().get_data());
}
enet_host_refuse_new_connections(host, refuse_connections);
#endif
IP_Address ip;
if (p_address.is_valid_ip_address()) {
ip = p_address;
} else {
#ifdef PANDEMONIUM_ENET
ip = IP::get_singleton()->resolve_hostname(p_address);
#else
ip = IP::get_singleton()->resolve_hostname(p_address, IP::TYPE_IPV4);
#endif
if (!ip.is_valid()) {
enet_host_destroy(host);
ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Couldn't resolve the server IP address or domain name.");
}
}
ENetAddress address;
#ifdef PANDEMONIUM_ENET
enet_address_set_ip(&address, ip.get_ipv6(), 16);
#else
if (!ip.is_ipv4()) {
enet_host_destroy(host);
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Connecting to an IPv6 server isn't supported when using vanilla ENet. Recompile Pandemonium with the bundled ENet library.");
}
address.host = *(uint32_t *)ip.get_ipv4();
#endif
address.port = p_port;
unique_id = _gen_unique_id();
// Initiate connection, allocating enough channels
ENetPeer *peer = enet_host_connect(host, &address, channel_count, unique_id);
if (peer == nullptr) {
enet_host_destroy(host);
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Couldn't connect to the ENet multiplayer server.");
}
// Technically safe to ignore the peer or anything else.
connection_status = CONNECTION_CONNECTING;
active = true;
server = false;
refuse_connections = false;
return OK;
}
void NetworkedMultiplayerENet::poll() {
ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
_pop_current_packet();
if (!host || !active) { // Might be disconnected
return;
}
ENetEvent event;
int ret = enet_host_service(host, &event, 0);
if (ret < 0) {
ERR_FAIL_MSG("Enet host service error");
} else if (ret == 0) {
return; // No events
}
/* Keep servicing until there are no available events left in the queue. */
do {
if (!host || !active) { // Check again after every event
return;
}
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT: {
// Store any relevant client information here.
if (server && refuse_connections) {
enet_peer_reset(event.peer);
break;
}
// A client joined with an invalid ID (negative values, 0, and 1 are reserved).
// Probably trying to exploit us.
if (server && ((int)event.data < 2 || peer_map.has((int)event.data))) {
enet_peer_reset(event.peer);
ERR_CONTINUE(true);
}
int *new_id = memnew(int);
*new_id = event.data;
if (*new_id == 0) { // Data zero is sent by server (enet won't let you configure this). Server is always 1.
*new_id = 1;
}
event.peer->data = new_id;
peer_map[*new_id] = event.peer;
connection_status = CONNECTION_CONNECTED; // If connecting, this means it connected to something!
emit_signal("peer_connected", *new_id);
if (server) {
// Do not notify other peers when server_relay is disabled.
if (!server_relay) {
break;
}
// Someone connected, notify all the peers available
for (RBMap<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
if (E->key() == *new_id) {
continue;
}
// Send existing peers to new peer
ENetPacket *packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]);
encode_uint32(E->key(), &packet->data[4]);
enet_peer_send(event.peer, SYSCH_CONFIG, packet);
// Send the new peer to existing peers
packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]);
encode_uint32(*new_id, &packet->data[4]);
enet_peer_send(E->get(), SYSCH_CONFIG, packet);
}
} else {
emit_signal("connection_succeeded");
}
} break;
case ENET_EVENT_TYPE_DISCONNECT: {
// Reset the peer's client information.
int *id = (int *)event.peer->data;
if (!id) {
if (!server) {
emit_signal("connection_failed");
}
// Never fully connected.
break;
}
if (!server) {
// Client just disconnected from server.
emit_signal("server_disconnected");
close_connection();
return;
} else if (server_relay) {
// Server just received a client disconnect and is in relay mode, notify everyone else.
for (RBMap<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
if (E->key() == *id) {
continue;
}
ENetPacket *packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]);
encode_uint32(*id, &packet->data[4]);
enet_peer_send(E->get(), SYSCH_CONFIG, packet);
}
}
emit_signal("peer_disconnected", *id);
peer_map.erase(*id);
memdelete(id);
} break;
case ENET_EVENT_TYPE_RECEIVE: {
if (event.channelID == SYSCH_CONFIG) {
// Some config message
ERR_CONTINUE(event.packet->dataLength < 8);
// Only server can send config messages
ERR_CONTINUE(server);
int msg = decode_uint32(&event.packet->data[0]);
int id = decode_uint32(&event.packet->data[4]);
switch (msg) {
case SYSMSG_ADD_PEER: {
peer_map[id] = NULL;
emit_signal("peer_connected", id);
} break;
case SYSMSG_REMOVE_PEER: {
peer_map.erase(id);
emit_signal("peer_disconnected", id);
} break;
}
enet_packet_destroy(event.packet);
} else if (event.channelID < channel_count) {
Packet packet;
packet.packet = event.packet;
uint32_t *id = (uint32_t *)event.peer->data;
ERR_CONTINUE(event.packet->dataLength < 8);
uint32_t source = decode_uint32(&event.packet->data[0]);
int target = decode_uint32(&event.packet->data[4]);
packet.from = source;
packet.channel = event.channelID;
if (server) {
// Someone is cheating and trying to fake the source!
ERR_CONTINUE(source != *id);
packet.from = *id;
if (target == 1) {
// To myself and only myself
incoming_packets.push_back(packet);
} else if (!server_relay) {
// When relaying is disabled, other destinations will only be processed by the server.
if (target == 0 || target < -1) {
incoming_packets.push_back(packet);
}
continue;
} else if (target == 0) {
// Re-send to everyone but sender :|
incoming_packets.push_back(packet);
// And make copies for sending
for (RBMap<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
if (uint32_t(E->key()) == source) { // Do not resend to self
continue;
}
ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, packet.packet->flags);
enet_peer_send(E->get(), event.channelID, packet2);
}
} else if (target < 0) {
// To all but one
// And make copies for sending
for (RBMap<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
if (uint32_t(E->key()) == source || E->key() == -target) { // Do not resend to self, also do not send to excluded
continue;
}
ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, packet.packet->flags);
enet_peer_send(E->get(), event.channelID, packet2);
}
if (-target != 1) {
// Server is not excluded
incoming_packets.push_back(packet);
} else {
// Server is excluded, erase packet
enet_packet_destroy(packet.packet);
}
} else {
// To someone else, specifically
ERR_CONTINUE(!peer_map.has(target));
enet_peer_send(peer_map[target], event.channelID, packet.packet);
}
} else {
incoming_packets.push_back(packet);
}
// Destroy packet later
} else {
ERR_CONTINUE(true);
}
} break;
case ENET_EVENT_TYPE_NONE: {
// Do nothing
} break;
}
} while (enet_host_check_events(host, &event) > 0);
}
bool NetworkedMultiplayerENet::is_server() const {
ERR_FAIL_COND_V_MSG(!active, false, "The multiplayer instance isn't currently active.");
return server;
}
void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
if (!active) {
return;
}
_pop_current_packet();
bool peers_disconnected = false;
for (RBMap<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
if (E->get()) {
enet_peer_disconnect_now(E->get(), unique_id);
int *id = (int *)(E->get()->data);
memdelete(id);
peers_disconnected = true;
}
}
if (peers_disconnected) {
enet_host_flush(host);
if (wait_usec > 0) {
OS::get_singleton()->delay_usec(wait_usec); // Wait for disconnection packets to send
}
}
enet_host_destroy(host);
active = false;
incoming_packets.clear();
peer_map.clear();
unique_id = 1; // Server is 1
connection_status = CONNECTION_DISCONNECTED;
}
void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_MSG(!is_server(), "Can't disconnect a peer when not acting as a server.");
ERR_FAIL_COND_MSG(!peer_map.has(p_peer), vformat("Peer ID %d not found in the list of peers.", p_peer));
if (now) {
int *id = (int *)peer_map[p_peer]->data;
enet_peer_disconnect_now(peer_map[p_peer], 0);
// enet_peer_disconnect_now doesn't generate ENET_EVENT_TYPE_DISCONNECT,
// notify everyone else, send disconnect signal & remove from peer_map like in poll()
if (server_relay) {
for (RBMap<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
if (E->key() == p_peer) {
continue;
}
ENetPacket *packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]);
encode_uint32(p_peer, &packet->data[4]);
enet_peer_send(E->get(), SYSCH_CONFIG, packet);
}
}
if (id) {
memdelete(id);
}
emit_signal("peer_disconnected", p_peer);
peer_map.erase(p_peer);
} else {
enet_peer_disconnect_later(peer_map[p_peer], 0);
}
}
int NetworkedMultiplayerENet::get_available_packet_count() const {
return incoming_packets.size();
}
Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
ERR_FAIL_COND_V_MSG(incoming_packets.size() == 0, ERR_UNAVAILABLE, "No incoming packets available.");
_pop_current_packet();
current_packet = incoming_packets.front()->get();
incoming_packets.pop_front();
*r_buffer = (const uint8_t *)(&current_packet.packet->data[8]);
r_buffer_size = current_packet.packet->dataLength - 8;
return OK;
}
Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
ERR_FAIL_COND_V_MSG(!active, ERR_UNCONFIGURED, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V_MSG(connection_status != CONNECTION_CONNECTED, ERR_UNCONFIGURED, "The multiplayer instance isn't currently connected to any server or client.");
int packet_flags = 0;
int channel = SYSCH_RELIABLE;
switch (transfer_mode) {
case TRANSFER_MODE_UNRELIABLE: {
if (always_ordered) {
packet_flags = 0;
} else {
packet_flags = ENET_PACKET_FLAG_UNSEQUENCED;
}
channel = SYSCH_UNRELIABLE;
packet_flags |= ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT;
} break;
case TRANSFER_MODE_UNRELIABLE_ORDERED: {
packet_flags = ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT;
channel = SYSCH_UNRELIABLE;
} break;
case TRANSFER_MODE_RELIABLE: {
packet_flags = ENET_PACKET_FLAG_RELIABLE;
channel = SYSCH_RELIABLE;
} break;
}
if (transfer_channel > SYSCH_CONFIG) {
channel = transfer_channel;
}
#ifdef DEBUG_ENABLED
if ((packet_flags & ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT) && p_buffer_size + 8 > ENET_HOST_DEFAULT_MTU) {
WARN_PRINT_ONCE(vformat("Sending %d bytes unrealiably which is above the MTU (%d), this will result in higher packet loss", p_buffer_size + 8, host->mtu));
}
#endif
RBMap<int, ENetPeer *>::Element *E = nullptr;
if (target_peer != 0) {
E = peer_map.find(ABS(target_peer));
ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, vformat("Invalid target peer: %d", target_peer));
}
ENetPacket *packet = enet_packet_create(nullptr, p_buffer_size + 8, packet_flags);
encode_uint32(unique_id, &packet->data[0]); // Source ID
encode_uint32(target_peer, &packet->data[4]); // Dest ID
memcpy(&packet->data[8], p_buffer, p_buffer_size);
if (server) {
if (target_peer == 0) {
enet_host_broadcast(host, channel, packet);
} else if (target_peer < 0) {
// Send to all but one
// and make copies for sending
int exclude = -target_peer;
for (RBMap<int, ENetPeer *>::Element *F = peer_map.front(); F; F = F->next()) {
if (F->key() == exclude) { // Exclude packet
continue;
}
ENetPacket *packet2 = enet_packet_create(packet->data, packet->dataLength, packet_flags);
enet_peer_send(F->get(), channel, packet2);
}
enet_packet_destroy(packet); // Original packet no longer needed
} else {
enet_peer_send(E->get(), channel, packet);
}
} else {
ERR_FAIL_COND_V(!peer_map.has(1), ERR_BUG);
enet_peer_send(peer_map[1], channel, packet); // Send to server for broadcast
}
enet_host_flush(host);
return OK;
}
int NetworkedMultiplayerENet::get_max_packet_size() const {
return 1 << 24; // Anything is good
}
void NetworkedMultiplayerENet::_pop_current_packet() {
if (current_packet.packet) {
enet_packet_destroy(current_packet.packet);
current_packet.packet = nullptr;
current_packet.from = 0;
current_packet.channel = -1;
}
}
NetworkedMultiplayerPeer::ConnectionStatus NetworkedMultiplayerENet::get_connection_status() const {
return connection_status;
}
uint32_t NetworkedMultiplayerENet::_gen_unique_id() const {
uint32_t hash = 0;
while (hash == 0 || hash == 1) {
hash = hash_djb2_one_32(
(uint32_t)OS::get_singleton()->get_ticks_usec());
hash = hash_djb2_one_32(
(uint32_t)OS::get_singleton()->get_unix_time(), hash);
hash = hash_djb2_one_32(
(uint32_t)OS::get_singleton()->get_user_data_dir().hash64(), hash);
hash = hash_djb2_one_32(
(uint32_t)((uint64_t)this), hash); // Rely on ASLR heap
hash = hash_djb2_one_32(
(uint32_t)((uint64_t)&hash), hash); // Rely on ASLR stack
hash = hash & 0x7FFFFFFF; // Make it compatible with unsigned, since negative ID is used for exclusion
}
return hash;
}
int NetworkedMultiplayerENet::get_unique_id() const {
ERR_FAIL_COND_V_MSG(!active, 0, "The multiplayer instance isn't currently active.");
return unique_id;
}
void NetworkedMultiplayerENet::set_refuse_new_connections(bool p_enable) {
refuse_connections = p_enable;
#ifdef PANDEMONIUM_ENET
if (active) {
enet_host_refuse_new_connections(host, p_enable);
}
#endif
}
bool NetworkedMultiplayerENet::is_refusing_new_connections() const {
return refuse_connections;
}
IP_Address NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), IP_Address(), vformat("Peer ID %d not found in the list of peers.", p_peer_id));
ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, IP_Address(), "Can't get the address of peers other than the server (ID -1) when acting as a client.");
ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == NULL, IP_Address(), vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
IP_Address out;
#ifdef PANDEMONIUM_ENET
out.set_ipv6((uint8_t *)&(peer_map[p_peer_id]->address.host));
#else
out.set_ipv4((uint8_t *)&(peer_map[p_peer_id]->address.host));
#endif
return out;
}
int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), 0, vformat("Peer ID %d not found in the list of peers.", p_peer_id));
ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, 0, "Can't get the address of peers other than the server (ID -1) when acting as a client.");
ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == NULL, 0, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
#ifdef PANDEMONIUM_ENET
return peer_map[p_peer_id]->address.port;
#else
return peer_map[p_peer_id]->address.port;
#endif
}
void NetworkedMultiplayerENet::set_peer_timeout(int p_peer_id, int p_timeout_limit, int p_timeout_min, int p_timeout_max) {
ERR_FAIL_COND_MSG(!peer_map.has(p_peer_id), vformat("Peer ID %d not found in the list of peers.", p_peer_id));
ERR_FAIL_COND_MSG(!is_server() && p_peer_id != 1, "Can't change the timeout of peers other then the server when acting as a client.");
ERR_FAIL_COND_MSG(peer_map[p_peer_id] == nullptr, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
ERR_FAIL_COND_MSG(p_timeout_limit > p_timeout_min || p_timeout_min > p_timeout_max, "Timeout limit must be less than minimum timeout, which itself must be less then maximum timeout");
enet_peer_timeout(peer_map[p_peer_id], p_timeout_limit, p_timeout_min, p_timeout_max);
}
void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
ERR_FAIL_COND_MSG(p_channel < -1 || p_channel >= channel_count, vformat("The transfer channel must be set between 0 and %d, inclusive (got %d).", channel_count - 1, p_channel));
ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, vformat("The channel %d is reserved.", SYSCH_CONFIG));
transfer_channel = p_channel;
}
int NetworkedMultiplayerENet::get_transfer_channel() const {
return transfer_channel;
}
void NetworkedMultiplayerENet::set_channel_count(int p_channel) {
ERR_FAIL_COND_MSG(active, "The channel count can't be set while the multiplayer instance is active.");
ERR_FAIL_COND_MSG(p_channel < SYSCH_MAX, vformat("The channel count must be greater than or equal to %d to account for reserved channels (got %d).", SYSCH_MAX, p_channel));
channel_count = p_channel;
}
int NetworkedMultiplayerENet::get_channel_count() const {
return channel_count;
}
void NetworkedMultiplayerENet::set_always_ordered(bool p_ordered) {
always_ordered = p_ordered;
}
bool NetworkedMultiplayerENet::is_always_ordered() const {
return always_ordered;
}
void NetworkedMultiplayerENet::set_server_relay_enabled(bool p_enabled) {
ERR_FAIL_COND_MSG(active, "Server relaying can't be toggled while the multiplayer instance is active.");
server_relay = p_enabled;
}
bool NetworkedMultiplayerENet::is_server_relay_enabled() const {
return server_relay;
}
void NetworkedMultiplayerENet::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_server", "port", "max_clients", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_server, DEFVAL(32), DEFVAL(0), DEFVAL(0));
ClassDB::bind_method(D_METHOD("create_client", "address", "port", "in_bandwidth", "out_bandwidth", "client_port"), &NetworkedMultiplayerENet::create_client, DEFVAL(0), DEFVAL(0), DEFVAL(0));
ClassDB::bind_method(D_METHOD("close_connection", "wait_usec"), &NetworkedMultiplayerENet::close_connection, DEFVAL(100));
ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "now"), &NetworkedMultiplayerENet::disconnect_peer, DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &NetworkedMultiplayerENet::set_bind_ip);
ClassDB::bind_method(D_METHOD("set_dtls_enabled", "enabled"), &NetworkedMultiplayerENet::set_dtls_enabled);
ClassDB::bind_method(D_METHOD("is_dtls_enabled"), &NetworkedMultiplayerENet::is_dtls_enabled);
ClassDB::bind_method(D_METHOD("set_dtls_key", "key"), &NetworkedMultiplayerENet::set_dtls_key);
ClassDB::bind_method(D_METHOD("set_dtls_certificate", "certificate"), &NetworkedMultiplayerENet::set_dtls_certificate);
ClassDB::bind_method(D_METHOD("set_dtls_verify_enabled", "enabled"), &NetworkedMultiplayerENet::set_dtls_verify_enabled);
ClassDB::bind_method(D_METHOD("is_dtls_verify_enabled"), &NetworkedMultiplayerENet::is_dtls_verify_enabled);
ClassDB::bind_method(D_METHOD("set_dtls_hostname", "hostname"), &NetworkedMultiplayerENet::set_dtls_hostname);
ClassDB::bind_method(D_METHOD("get_dtls_hostname"), &NetworkedMultiplayerENet::get_dtls_hostname);
ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &NetworkedMultiplayerENet::get_peer_address);
ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &NetworkedMultiplayerENet::get_peer_port);
ClassDB::bind_method(D_METHOD("set_peer_timeout", "id", "timeout_limit", "timeout_min", "timeout_max"), &NetworkedMultiplayerENet::set_peer_timeout);
ClassDB::bind_method(D_METHOD("get_packet_channel"), &NetworkedMultiplayerENet::get_packet_channel);
ClassDB::bind_method(D_METHOD("get_last_packet_channel"), &NetworkedMultiplayerENet::get_last_packet_channel);
ClassDB::bind_method(D_METHOD("set_transfer_channel", "channel"), &NetworkedMultiplayerENet::set_transfer_channel);
ClassDB::bind_method(D_METHOD("get_transfer_channel"), &NetworkedMultiplayerENet::get_transfer_channel);
ClassDB::bind_method(D_METHOD("set_channel_count", "channels"), &NetworkedMultiplayerENet::set_channel_count);
ClassDB::bind_method(D_METHOD("get_channel_count"), &NetworkedMultiplayerENet::get_channel_count);
ClassDB::bind_method(D_METHOD("set_always_ordered", "ordered"), &NetworkedMultiplayerENet::set_always_ordered);
ClassDB::bind_method(D_METHOD("is_always_ordered"), &NetworkedMultiplayerENet::is_always_ordered);
ClassDB::bind_method(D_METHOD("set_server_relay_enabled", "enabled"), &NetworkedMultiplayerENet::set_server_relay_enabled);
ClassDB::bind_method(D_METHOD("is_server_relay_enabled"), &NetworkedMultiplayerENet::is_server_relay_enabled);
ADD_PROPERTY(PropertyInfo(Variant::INT, "transfer_channel"), "set_transfer_channel", "get_transfer_channel");
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel_count"), "set_channel_count", "get_channel_count");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "always_ordered"), "set_always_ordered", "is_always_ordered");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "server_relay"), "set_server_relay_enabled", "is_server_relay_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dtls_verify"), "set_dtls_verify_enabled", "is_dtls_verify_enabled");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "dtls_hostname"), "set_dtls_hostname", "get_dtls_hostname");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_dtls"), "set_dtls_enabled", "is_dtls_enabled");
}
NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
active = false;
server = false;
refuse_connections = false;
server_relay = true;
unique_id = 0;
target_peer = 0;
current_packet.packet = nullptr;
transfer_mode = TRANSFER_MODE_RELIABLE;
channel_count = SYSCH_MAX;
transfer_channel = -1;
always_ordered = false;
connection_status = CONNECTION_DISCONNECTED;
bind_ip = IP_Address("*");
dtls_enabled = false;
dtls_verify = true;
}
NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
if (active) {
close_connection();
}
}
// Sets IP for ENet to bind when using create_server or create_client
// if no IP is set, then ENet bind to ENET_HOST_ANY
void NetworkedMultiplayerENet::set_bind_ip(const IP_Address &p_ip) {
ERR_FAIL_COND_MSG(!p_ip.is_valid() && !p_ip.is_wildcard(), vformat("Invalid bind IP address: %s", String(p_ip)));
bind_ip = p_ip;
}
void NetworkedMultiplayerENet::set_dtls_enabled(bool p_enabled) {
ERR_FAIL_COND(active);
dtls_enabled = p_enabled;
}
bool NetworkedMultiplayerENet::is_dtls_enabled() const {
return dtls_enabled;
}
void NetworkedMultiplayerENet::set_dtls_verify_enabled(bool p_enabled) {
ERR_FAIL_COND(active);
dtls_verify = p_enabled;
}
bool NetworkedMultiplayerENet::is_dtls_verify_enabled() const {
return dtls_verify;
}
void NetworkedMultiplayerENet::set_dtls_key(Ref<CryptoKey> p_key) {
ERR_FAIL_COND(active);
dtls_key = p_key;
}
void NetworkedMultiplayerENet::set_dtls_certificate(Ref<X509Certificate> p_cert) {
ERR_FAIL_COND(active);
dtls_cert = p_cert;
}
void NetworkedMultiplayerENet::set_dtls_hostname(const String &p_hostname) {
ERR_FAIL_COND(active);
dtls_hostname = p_hostname;
}
String NetworkedMultiplayerENet::get_dtls_hostname() const {
return dtls_hostname;
}

View File

@ -1,137 +0,0 @@
#ifndef NETWORKED_MULTIPLAYER_ENET_H
#define NETWORKED_MULTIPLAYER_ENET_H
/* networked_multiplayer_enet.h */
#include "core/crypto/crypto.h"
#include "core/io/networked_multiplayer_peer.h"
#include <enet/enet.h>
class NetworkedMultiplayerENet : public NetworkedMultiplayerPeer {
GDCLASS(NetworkedMultiplayerENet, NetworkedMultiplayerPeer);
private:
enum {
SYSMSG_ADD_PEER,
SYSMSG_REMOVE_PEER
};
enum {
SYSCH_CONFIG,
SYSCH_RELIABLE,
SYSCH_UNRELIABLE,
SYSCH_MAX
};
bool active;
bool server;
uint32_t unique_id;
int target_peer;
TransferMode transfer_mode;
int transfer_channel;
int channel_count;
bool always_ordered;
ENetEvent event;
ENetPeer *peer;
ENetHost *host;
bool refuse_connections;
bool server_relay;
ConnectionStatus connection_status;
RBMap<int, ENetPeer *> peer_map;
struct Packet {
ENetPacket *packet;
int from;
int channel;
};
List<Packet> incoming_packets;
Packet current_packet;
uint32_t _gen_unique_id() const;
void _pop_current_packet();
Vector<uint8_t> src_compressor_mem;
Vector<uint8_t> dst_compressor_mem;
IP_Address bind_ip;
bool dtls_enabled;
Ref<CryptoKey> dtls_key;
Ref<X509Certificate> dtls_cert;
bool dtls_verify;
String dtls_hostname;
protected:
static void _bind_methods();
public:
virtual void set_transfer_mode(TransferMode p_mode);
virtual TransferMode get_transfer_mode() const;
virtual void set_target_peer(int p_peer);
virtual int get_packet_peer() const;
virtual IP_Address get_peer_address(int p_peer_id) const;
virtual int get_peer_port(int p_peer_id) const;
void set_peer_timeout(int p_peer_id, int p_timeout_limit, int p_timeout_min, int p_timeout_max);
Error create_server(int p_port, int p_max_clients = 32, int p_in_bandwidth = 0, int p_out_bandwidth = 0);
Error create_client(const String &p_address, int p_port, int p_in_bandwidth = 0, int p_out_bandwidth = 0, int p_client_port = 0);
void close_connection(uint32_t wait_usec = 100);
void disconnect_peer(int p_peer, bool now = false);
virtual void poll();
virtual bool is_server() const;
virtual int get_available_packet_count() const;
virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); ///< buffer is GONE after next get_packet
virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
virtual int get_max_packet_size() const;
virtual ConnectionStatus get_connection_status() const;
virtual void set_refuse_new_connections(bool p_enable);
virtual bool is_refusing_new_connections() const;
virtual int get_unique_id() const;
int get_packet_channel() const;
int get_last_packet_channel() const;
void set_transfer_channel(int p_channel);
int get_transfer_channel() const;
void set_channel_count(int p_channel);
int get_channel_count() const;
void set_always_ordered(bool p_ordered);
bool is_always_ordered() const;
void set_server_relay_enabled(bool p_enabled);
bool is_server_relay_enabled() const;
NetworkedMultiplayerENet();
~NetworkedMultiplayerENet();
void set_bind_ip(const IP_Address &p_ip);
void set_dtls_enabled(bool p_enabled);
bool is_dtls_enabled() const;
void set_dtls_verify_enabled(bool p_enabled);
bool is_dtls_verify_enabled() const;
void set_dtls_key(Ref<CryptoKey> p_key);
void set_dtls_certificate(Ref<X509Certificate> p_cert);
void set_dtls_hostname(const String &p_hostname);
String get_dtls_hostname() const;
};
#endif // NETWORKED_MULTIPLAYER_ENET_H

View File

@ -1,31 +0,0 @@
/* register_types.cpp */
#include "register_types.h"
#include "core/error/error_macros.h"
#include "networked_multiplayer_enet.h"
static bool enet_ok = false;
void register_enet_types(ModuleRegistrationLevel p_level) {
if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) {
if (enet_initialize() != 0) {
ERR_PRINT("ENet initialization failure");
} else {
enet_ok = true;
}
}
if (p_level == MODULE_REGISTRATION_LEVEL_SCENE) {
ClassDB::register_class<NetworkedMultiplayerENet>();
}
}
void unregister_enet_types(ModuleRegistrationLevel p_level) {
if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) {
if (enet_ok) {
enet_deinitialize();
}
}
}

View File

@ -1,12 +0,0 @@
#ifndef ENET_REGISTER_TYPES_H
#define ENET_REGISTER_TYPES_H
/* register_types.h */
#include "modules/register_module_types.h"
void register_enet_types(ModuleRegistrationLevel p_level);
void unregister_enet_types(ModuleRegistrationLevel p_level);
#endif // ENET_REGISTER_TYPES_H

View File

@ -1,134 +0,0 @@
#!/usr/bin/env python
Import("env")
Import("env_modules")
from compat import isbasestring
env_freetype = env_modules.Clone()
# Thirdparty source files
thirdparty_obj = []
thirdparty_dir = "#modules/freetype/freetype/"
thirdparty_sources = [
"src/autofit/autofit.c",
"src/base/ftbase.c",
"src/base/ftbbox.c",
"src/base/ftbdf.c",
"src/base/ftbitmap.c",
"src/base/ftcid.c",
"src/base/ftdebug.c",
"src/base/ftfstype.c",
"src/base/ftgasp.c",
"src/base/ftglyph.c",
"src/base/ftgxval.c",
"src/base/ftinit.c",
"src/base/ftmm.c",
"src/base/ftotval.c",
"src/base/ftpatent.c",
"src/base/ftpfr.c",
"src/base/ftstroke.c",
"src/base/ftsynth.c",
"src/base/ftsystem.c",
"src/base/fttype1.c",
"src/base/ftwinfnt.c",
"src/bdf/bdf.c",
"src/bzip2/ftbzip2.c",
"src/cache/ftcache.c",
"src/cff/cff.c",
"src/cid/type1cid.c",
"src/gxvalid/gxvalid.c",
"src/gzip/ftgzip.c",
"src/lzw/ftlzw.c",
"src/otvalid/otvalid.c",
"src/pcf/pcf.c",
"src/pfr/pfr.c",
"src/psaux/psaux.c",
"src/pshinter/pshinter.c",
"src/psnames/psnames.c",
"src/raster/raster.c",
"src/sdf/sdf.c",
"src/svg/svg.c",
"src/smooth/smooth.c",
"src/truetype/truetype.c",
"src/type1/type1.c",
"src/type42/type42.c",
"src/winfonts/winfnt.c",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
thirdparty_brotli_dir = "#modules/freetype/brotli/"
thirdparty_brotli_sources = [
"common/constants.c",
"common/context.c",
"common/dictionary.c",
"common/platform.c",
"common/shared_dictionary.c",
"common/transform.c",
"dec/bit_reader.c",
"dec/decode.c",
"dec/huffman.c",
"dec/state.c",
]
thirdparty_sources += [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources]
env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"])
env_freetype.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"])
if env["platform"] == "uwp":
# Include header for UWP to fix build issues
env_freetype.Append(CCFLAGS=["/FI", '"modules/freetype/uwpdef.h"'])
# Globally too, as freetype is used in scene (see bottom)
env.Append(CCFLAGS=["/FI", '"modules/freetype/uwpdef.h"'])
env_freetype.Prepend(CPPPATH=[thirdparty_dir + "/include"])
# Also needed in main env for scene/
env.Prepend(CPPPATH=[thirdparty_dir + "/include"])
env_freetype.Append(CPPDEFINES=["FT2_BUILD_LIBRARY", "FT_CONFIG_OPTION_USE_PNG", "FT_CONFIG_OPTION_SYSTEM_ZLIB"])
if env["target"] == "debug":
env_freetype.Append(CPPDEFINES=["ZLIB_DEBUG"])
# Also requires libpng headers
env_freetype.Prepend(CPPPATH=["#modules/png/libpng/"])
sfnt = thirdparty_dir + "src/sfnt/sfnt.c"
# Must be done after all CPPDEFINES are being set so we can copy them.
if env["platform"] == "javascript":
# Forcibly undefine this macro so SIMD is not used in this file,
# since currently unsupported in WASM
tmp_env = env_freetype.Clone()
tmp_env.disable_warnings()
tmp_env.Append(CPPFLAGS=["-U__OPTIMIZE__"])
sfnt = tmp_env.Object(sfnt)
thirdparty_sources += [sfnt]
env_thirdparty = env_freetype.Clone()
env_thirdparty.disable_warnings()
lib = env_thirdparty.add_library("freetype_builtin", thirdparty_sources)
thirdparty_obj += lib
# Needs to be appended to arrive after libscene in the linker call,
# but we don't want it to arrive *after* system libs, so manual hack
# LIBS contains first SCons Library objects ("SCons.Node.FS.File object")
# and then plain strings for system library. We insert between the two.
inserted = False
for idx, linklib in enumerate(env["LIBS"]):
if isbasestring(linklib): # first system lib such as "X11", otherwise SCons lib object
env["LIBS"].insert(idx, lib)
inserted = True
break
if not inserted:
env.Append(LIBS=[lib])
# Pandemonium source files
module_obj = []
env_freetype.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj
# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)

View File

@ -1,19 +0,0 @@
Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,15 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
#include "constants.h"
const BrotliPrefixCodeRange
_kBrotliPrefixCodeRanges[BROTLI_NUM_BLOCK_LEN_SYMBOLS] = {
{1, 2}, {5, 2}, {9, 2}, {13, 2}, {17, 3}, {25, 3},
{33, 3}, {41, 3}, {49, 4}, {65, 4}, {81, 4}, {97, 4},
{113, 5}, {145, 5}, {177, 5}, {209, 5}, {241, 6}, {305, 6},
{369, 7}, {497, 8}, {753, 9}, {1265, 10}, {2289, 11}, {4337, 12},
{8433, 13}, {16625, 24}};

View File

@ -1,201 +0,0 @@
/* Copyright 2016 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/**
* @file
* Common constants used in decoder and encoder API.
*/
#ifndef BROTLI_COMMON_CONSTANTS_H_
#define BROTLI_COMMON_CONSTANTS_H_
#include <brotli/port.h>
#include <brotli/types.h>
#include "platform.h"
/* Specification: 7.3. Encoding of the context map */
#define BROTLI_CONTEXT_MAP_MAX_RLE 16
/* Specification: 2. Compressed representation overview */
#define BROTLI_MAX_NUMBER_OF_BLOCK_TYPES 256
/* Specification: 3.3. Alphabet sizes: insert-and-copy length */
#define BROTLI_NUM_LITERAL_SYMBOLS 256
#define BROTLI_NUM_COMMAND_SYMBOLS 704
#define BROTLI_NUM_BLOCK_LEN_SYMBOLS 26
#define BROTLI_MAX_CONTEXT_MAP_SYMBOLS (BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + \
BROTLI_CONTEXT_MAP_MAX_RLE)
#define BROTLI_MAX_BLOCK_TYPE_SYMBOLS (BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + 2)
/* Specification: 3.5. Complex prefix codes */
#define BROTLI_REPEAT_PREVIOUS_CODE_LENGTH 16
#define BROTLI_REPEAT_ZERO_CODE_LENGTH 17
#define BROTLI_CODE_LENGTH_CODES (BROTLI_REPEAT_ZERO_CODE_LENGTH + 1)
/* "code length of 8 is repeated" */
#define BROTLI_INITIAL_REPEATED_CODE_LENGTH 8
/* "Large Window Brotli" */
/**
* The theoretical maximum number of distance bits specified for large window
* brotli, for 64-bit encoders and decoders. Even when in practice 32-bit
* encoders and decoders only support up to 30 max distance bits, the value is
* set to 62 because it affects the large window brotli file format.
* Specifically, it affects the encoding of simple huffman tree for distances,
* see Specification RFC 7932 chapter 3.4.
*/
#define BROTLI_LARGE_MAX_DISTANCE_BITS 62U
#define BROTLI_LARGE_MIN_WBITS 10
/**
* The maximum supported large brotli window bits by the encoder and decoder.
* Large window brotli allows up to 62 bits, however the current encoder and
* decoder, designed for 32-bit integers, only support up to 30 bits maximum.
*/
#define BROTLI_LARGE_MAX_WBITS 30
/* Specification: 4. Encoding of distances */
#define BROTLI_NUM_DISTANCE_SHORT_CODES 16
/**
* Maximal number of "postfix" bits.
*
* Number of "postfix" bits is stored as 2 bits in meta-block header.
*/
#define BROTLI_MAX_NPOSTFIX 3
#define BROTLI_MAX_NDIRECT 120
#define BROTLI_MAX_DISTANCE_BITS 24U
#define BROTLI_DISTANCE_ALPHABET_SIZE(NPOSTFIX, NDIRECT, MAXNBITS) ( \
BROTLI_NUM_DISTANCE_SHORT_CODES + (NDIRECT) + \
((MAXNBITS) << ((NPOSTFIX) + 1)))
/* BROTLI_NUM_DISTANCE_SYMBOLS == 1128 */
#define BROTLI_NUM_DISTANCE_SYMBOLS \
BROTLI_DISTANCE_ALPHABET_SIZE( \
BROTLI_MAX_NDIRECT, BROTLI_MAX_NPOSTFIX, BROTLI_LARGE_MAX_DISTANCE_BITS)
/* ((1 << 26) - 4) is the maximal distance that can be expressed in RFC 7932
brotli stream using NPOSTFIX = 0 and NDIRECT = 0. With other NPOSTFIX and
NDIRECT values distances up to ((1 << 29) + 88) could be expressed. */
#define BROTLI_MAX_DISTANCE 0x3FFFFFC
/* ((1 << 31) - 4) is the safe distance limit. Using this number as a limit
allows safe distance calculation without overflows, given the distance
alphabet size is limited to corresponding size
(see kLargeWindowDistanceCodeLimits). */
#define BROTLI_MAX_ALLOWED_DISTANCE 0x7FFFFFFC
/* Specification: 4. Encoding of Literal Insertion Lengths and Copy Lengths */
#define BROTLI_NUM_INS_COPY_CODES 24
/* 7.1. Context modes and context ID lookup for literals */
/* "context IDs for literals are in the range of 0..63" */
#define BROTLI_LITERAL_CONTEXT_BITS 6
/* 7.2. Context ID for distances */
#define BROTLI_DISTANCE_CONTEXT_BITS 2
/* 9.1. Format of the Stream Header */
/* Number of slack bytes for window size. Don't confuse
with BROTLI_NUM_DISTANCE_SHORT_CODES. */
#define BROTLI_WINDOW_GAP 16
#define BROTLI_MAX_BACKWARD_LIMIT(W) (((size_t)1 << (W)) - BROTLI_WINDOW_GAP)
typedef struct BrotliDistanceCodeLimit {
uint32_t max_alphabet_size;
uint32_t max_distance;
} BrotliDistanceCodeLimit;
/* This function calculates maximal size of distance alphabet, such that the
distances greater than the given values can not be represented.
This limits are designed to support fast and safe 32-bit decoders.
"32-bit" means that signed integer values up to ((1 << 31) - 1) could be
safely expressed.
Brotli distance alphabet symbols do not represent consecutive distance
ranges. Each distance alphabet symbol (excluding direct distances and short
codes), represent interleaved (for NPOSTFIX > 0) range of distances.
A "group" of consecutive (1 << NPOSTFIX) symbols represent non-interleaved
range. Two consecutive groups require the same amount of "extra bits".
It is important that distance alphabet represents complete "groups".
To avoid complex logic on encoder side about interleaved ranges
it was decided to restrict both sides to complete distance code "groups".
*/
BROTLI_UNUSED_FUNCTION BrotliDistanceCodeLimit BrotliCalculateDistanceCodeLimit(
uint32_t max_distance, uint32_t npostfix, uint32_t ndirect) {
BrotliDistanceCodeLimit result;
/* Marking this function as unused, because not all files
including "constants.h" use it -> compiler warns about that. */
BROTLI_UNUSED(&BrotliCalculateDistanceCodeLimit);
if (max_distance <= ndirect) {
/* This case never happens / exists only for the sake of completeness. */
result.max_alphabet_size = max_distance + BROTLI_NUM_DISTANCE_SHORT_CODES;
result.max_distance = max_distance;
return result;
} else {
/* The first prohibited value. */
uint32_t forbidden_distance = max_distance + 1;
/* Subtract "directly" encoded region. */
uint32_t offset = forbidden_distance - ndirect - 1;
uint32_t ndistbits = 0;
uint32_t tmp;
uint32_t half;
uint32_t group;
/* Postfix for the last dcode in the group. */
uint32_t postfix = (1u << npostfix) - 1;
uint32_t extra;
uint32_t start;
/* Remove postfix and "head-start". */
offset = (offset >> npostfix) + 4;
/* Calculate the number of distance bits. */
tmp = offset / 2;
/* Poor-man's log2floor, to avoid extra dependencies. */
while (tmp != 0) {ndistbits++; tmp = tmp >> 1;}
/* One bit is covered with subrange addressing ("half"). */
ndistbits--;
/* Find subrange. */
half = (offset >> ndistbits) & 1;
/* Calculate the "group" part of dcode. */
group = ((ndistbits - 1) << 1) | half;
/* Calculated "group" covers the prohibited distance value. */
if (group == 0) {
/* This case is added for correctness; does not occur for limit > 128. */
result.max_alphabet_size = ndirect + BROTLI_NUM_DISTANCE_SHORT_CODES;
result.max_distance = ndirect;
return result;
}
/* Decrement "group", so it is the last permitted "group". */
group--;
/* After group was decremented, ndistbits and half must be recalculated. */
ndistbits = (group >> 1) + 1;
/* The last available distance in the subrange has all extra bits set. */
extra = (1u << ndistbits) - 1;
/* Calculate region start. NB: ndistbits >= 1. */
start = (1u << (ndistbits + 1)) - 4;
/* Move to subregion. */
start += (group & 1) << ndistbits;
/* Calculate the alphabet size. */
result.max_alphabet_size = ((group << npostfix) | postfix) + ndirect +
BROTLI_NUM_DISTANCE_SHORT_CODES + 1;
/* Calculate the maximal distance representable by alphabet. */
result.max_distance = ((start + extra) << npostfix) + postfix + ndirect + 1;
return result;
}
}
/* Represents the range of values belonging to a prefix code:
[offset, offset + 2^nbits) */
typedef struct {
uint16_t offset;
uint8_t nbits;
} BrotliPrefixCodeRange;
/* "Soft-private", it is exported, but not "advertised" as API. */
BROTLI_COMMON_API extern const BrotliPrefixCodeRange
_kBrotliPrefixCodeRanges[BROTLI_NUM_BLOCK_LEN_SYMBOLS];
#endif /* BROTLI_COMMON_CONSTANTS_H_ */

View File

@ -1,156 +0,0 @@
#include "context.h"
#include <brotli/types.h>
/* Common context lookup table for all context modes. */
const uint8_t _kBrotliContextLookupTable[2048] = {
/* CONTEXT_LSB6, last byte. */
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
/* CONTEXT_LSB6, second last byte, */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* CONTEXT_MSB6, last byte. */
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11,
12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27,
28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,
32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35,
36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,
40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43,
44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47,
48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51,
52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55,
56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59,
60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63,
/* CONTEXT_MSB6, second last byte, */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* CONTEXT_UTF8, last byte. */
/* ASCII range. */
0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12,
44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12,
12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48,
52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12,
12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56,
60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0,
/* UTF8 continuation byte range. */
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
/* UTF8 lead byte range. */
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
/* CONTEXT_UTF8 second last byte. */
/* ASCII range. */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0,
/* UTF8 continuation byte range. */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* UTF8 lead byte range. */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */
0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56,
/* CONTEXT_SIGNED, second last byte. */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
};

View File

@ -1,113 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Lookup table to map the previous two bytes to a context id.
There are four different context modeling modes defined here:
CONTEXT_LSB6: context id is the least significant 6 bits of the last byte,
CONTEXT_MSB6: context id is the most significant 6 bits of the last byte,
CONTEXT_UTF8: second-order context model tuned for UTF8-encoded text,
CONTEXT_SIGNED: second-order context model tuned for signed integers.
If |p1| and |p2| are the previous two bytes, and |mode| is current context
mode, we calculate the context as:
context = ContextLut(mode)[p1] | ContextLut(mode)[p2 + 256].
For CONTEXT_UTF8 mode, if the previous two bytes are ASCII characters
(i.e. < 128), this will be equivalent to
context = 4 * context1(p1) + context2(p2),
where context1 is based on the previous byte in the following way:
0 : non-ASCII control
1 : \t, \n, \r
2 : space
3 : other punctuation
4 : " '
5 : %
6 : ( < [ {
7 : ) > ] }
8 : , ; :
9 : .
10 : =
11 : number
12 : upper-case vowel
13 : upper-case consonant
14 : lower-case vowel
15 : lower-case consonant
and context2 is based on the second last byte:
0 : control, space
1 : punctuation
2 : upper-case letter, number
3 : lower-case letter
If the last byte is ASCII, and the second last byte is not (in a valid UTF8
stream it will be a continuation byte, value between 128 and 191), the
context is the same as if the second last byte was an ASCII control or space.
If the last byte is a UTF8 lead byte (value >= 192), then the next byte will
be a continuation byte and the context id is 2 or 3 depending on the LSB of
the last byte and to a lesser extent on the second last byte if it is ASCII.
If the last byte is a UTF8 continuation byte, the second last byte can be:
- continuation byte: the next byte is probably ASCII or lead byte (assuming
4-byte UTF8 characters are rare) and the context id is 0 or 1.
- lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1
- lead byte (208 - 255): next byte is continuation byte, context is 2 or 3
The possible value combinations of the previous two bytes, the range of
context ids and the type of the next byte is summarized in the table below:
|--------\-----------------------------------------------------------------|
| \ Last byte |
| Second \---------------------------------------------------------------|
| last byte \ ASCII | cont. byte | lead byte |
| \ (0-127) | (128-191) | (192-) |
|=============|===================|=====================|==================|
| ASCII | next: ASCII/lead | not valid | next: cont. |
| (0-127) | context: 4 - 63 | | context: 2 - 3 |
|-------------|-------------------|---------------------|------------------|
| cont. byte | next: ASCII/lead | next: ASCII/lead | next: cont. |
| (128-191) | context: 4 - 63 | context: 0 - 1 | context: 2 - 3 |
|-------------|-------------------|---------------------|------------------|
| lead byte | not valid | next: ASCII/lead | not valid |
| (192-207) | | context: 0 - 1 | |
|-------------|-------------------|---------------------|------------------|
| lead byte | not valid | next: cont. | not valid |
| (208-) | | context: 2 - 3 | |
|-------------|-------------------|---------------------|------------------|
*/
#ifndef BROTLI_COMMON_CONTEXT_H_
#define BROTLI_COMMON_CONTEXT_H_
#include <brotli/port.h>
#include <brotli/types.h>
typedef enum ContextType {
CONTEXT_LSB6 = 0,
CONTEXT_MSB6 = 1,
CONTEXT_UTF8 = 2,
CONTEXT_SIGNED = 3
} ContextType;
/* "Soft-private", it is exported, but not "advertised" as API. */
/* Common context lookup table for all context modes. */
BROTLI_COMMON_API extern const uint8_t _kBrotliContextLookupTable[2048];
typedef const uint8_t* ContextLut;
/* typeof(MODE) == ContextType; returns ContextLut */
#define BROTLI_CONTEXT_LUT(MODE) (&_kBrotliContextLookupTable[(MODE) << 9])
/* typeof(LUT) == ContextLut */
#define BROTLI_CONTEXT(P1, P2, LUT) ((LUT)[P1] | ((LUT) + 256)[P2])
#endif /* BROTLI_COMMON_CONTEXT_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Collection of static dictionary words. */
#ifndef BROTLI_COMMON_DICTIONARY_H_
#define BROTLI_COMMON_DICTIONARY_H_
#include <brotli/port.h>
#include <brotli/types.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
typedef struct BrotliDictionary {
/**
* Number of bits to encode index of dictionary word in a bucket.
*
* Specification: Appendix A. Static Dictionary Data
*
* Words in a dictionary are bucketed by length.
* @c 0 means that there are no words of a given length.
* Dictionary consists of words with length of [4..24] bytes.
* Values at [0..3] and [25..31] indices should not be addressed.
*/
uint8_t size_bits_by_length[32];
/* assert(offset[i + 1] == offset[i] + (bits[i] ? (i << bits[i]) : 0)) */
uint32_t offsets_by_length[32];
/* assert(data_size == offsets_by_length[31]) */
size_t data_size;
/* Data array is not bound, and should obey to size_bits_by_length values.
Specified size matches default (RFC 7932) dictionary. Its size is
defined by data_size */
const uint8_t* data;
} BrotliDictionary;
BROTLI_COMMON_API const BrotliDictionary* BrotliGetDictionary(void);
/**
* Sets dictionary data.
*
* When dictionary data is already set / present, this method is no-op.
*
* Dictionary data MUST be provided before BrotliGetDictionary is invoked.
* This method is used ONLY in multi-client environment (e.g. C + Java),
* to reduce storage by sharing single dictionary between implementations.
*/
BROTLI_COMMON_API void BrotliSetDictionaryData(const uint8_t* data);
#define BROTLI_MIN_DICTIONARY_WORD_LENGTH 4
#define BROTLI_MAX_DICTIONARY_WORD_LENGTH 24
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_COMMON_DICTIONARY_H_ */

View File

@ -1,23 +0,0 @@
/* Copyright 2016 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
#include <stdlib.h>
#include <brotli/types.h>
#include "platform.h"
/* Default brotli_alloc_func */
void* BrotliDefaultAllocFunc(void* opaque, size_t size) {
BROTLI_UNUSED(opaque);
return malloc(size);
}
/* Default brotli_free_func */
void BrotliDefaultFreeFunc(void* opaque, void* address) {
BROTLI_UNUSED(opaque);
free(address);
}

View File

@ -1,525 +0,0 @@
/* Copyright 2016 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Macros for compiler / platform specific features and build options.
Build options are:
* BROTLI_BUILD_32_BIT disables 64-bit optimizations
* BROTLI_BUILD_64_BIT forces to use 64-bit optimizations
* BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
* BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
* BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
* BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs
* BROTLI_BUILD_NO_UNALIGNED_READ_FAST forces off the fast-unaligned-read
optimizations (mainly for testing purposes).
* BROTLI_DEBUG dumps file name and line number when decoder detects stream
or memory error
* BROTLI_ENABLE_LOG enables asserts and dumps various state information
*/
#ifndef BROTLI_COMMON_PLATFORM_H_
#define BROTLI_COMMON_PLATFORM_H_
#include <string.h> /* memcpy */
#include <brotli/port.h>
#include <brotli/types.h>
#if defined(OS_LINUX) || defined(OS_CYGWIN) || defined(__EMSCRIPTEN__)
#include <endian.h>
#elif defined(OS_FREEBSD)
#include <machine/endian.h>
#elif defined(OS_MACOSX)
#include <machine/endian.h>
/* Let's try and follow the Linux convention */
#define BROTLI_X_BYTE_ORDER BYTE_ORDER
#define BROTLI_X_LITTLE_ENDIAN LITTLE_ENDIAN
#define BROTLI_X_BIG_ENDIAN BIG_ENDIAN
#endif
#if BROTLI_MSVC_VERSION_CHECK(18, 0, 0)
#include <intrin.h>
#endif
#if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG)
#include <assert.h>
#include <stdio.h>
#endif
/* The following macros were borrowed from https://github.com/nemequ/hedley
* with permission of original author - Evan Nemerson <evan@nemerson.com> */
/* >>> >>> >>> hedley macros */
/* Define "BROTLI_PREDICT_TRUE" and "BROTLI_PREDICT_FALSE" macros for capable
compilers.
To apply compiler hint, enclose the branching condition into macros, like this:
if (BROTLI_PREDICT_TRUE(zero == 0)) {
// main execution path
} else {
// compiler should place this code outside of main execution path
}
OR:
if (BROTLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) {
// compiler should place this code outside of main execution path
}
*/
#if BROTLI_GNUC_HAS_BUILTIN(__builtin_expect, 3, 0, 0) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
BROTLI_SUNPRO_VERSION_CHECK(5, 15, 0) || \
BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \
BROTLI_TI_VERSION_CHECK(7, 3, 0) || \
BROTLI_TINYC_VERSION_CHECK(0, 9, 27)
#define BROTLI_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
#define BROTLI_PREDICT_FALSE(x) (__builtin_expect(x, 0))
#else
#define BROTLI_PREDICT_FALSE(x) (x)
#define BROTLI_PREDICT_TRUE(x) (x)
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(__cplusplus)
#define BROTLI_RESTRICT restrict
#elif BROTLI_GNUC_VERSION_CHECK(3, 1, 0) || \
BROTLI_MSVC_VERSION_CHECK(14, 0, 0) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \
BROTLI_PGI_VERSION_CHECK(17, 10, 0) || \
BROTLI_TI_VERSION_CHECK(8, 0, 0) || \
BROTLI_IAR_VERSION_CHECK(8, 0, 0) || \
(BROTLI_SUNPRO_VERSION_CHECK(5, 14, 0) && defined(__cplusplus))
#define BROTLI_RESTRICT __restrict
#elif BROTLI_SUNPRO_VERSION_CHECK(5, 3, 0) && !defined(__cplusplus)
#define BROTLI_RESTRICT _Restrict
#else
#define BROTLI_RESTRICT
#endif
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
(defined(__cplusplus) && (__cplusplus >= 199711L))
#define BROTLI_MAYBE_INLINE inline
#elif defined(__GNUC_STDC_INLINE__) || defined(__GNUC_GNU_INLINE__) || \
BROTLI_ARM_VERSION_CHECK(6, 2, 0)
#define BROTLI_MAYBE_INLINE __inline__
#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0) || \
BROTLI_ARM_VERSION_CHECK(4, 1, 0) || BROTLI_TI_VERSION_CHECK(8, 0, 0)
#define BROTLI_MAYBE_INLINE __inline
#else
#define BROTLI_MAYBE_INLINE
#endif
#if BROTLI_GNUC_HAS_ATTRIBUTE(always_inline, 4, 0, 0) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \
BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \
BROTLI_TI_VERSION_CHECK(8, 0, 0) || \
(BROTLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
#define BROTLI_INLINE BROTLI_MAYBE_INLINE __attribute__((__always_inline__))
#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
#define BROTLI_INLINE BROTLI_MAYBE_INLINE __forceinline
#elif BROTLI_TI_VERSION_CHECK(7, 0, 0) && defined(__cplusplus)
#define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
#elif BROTLI_IAR_VERSION_CHECK(8, 0, 0)
#define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma("inline=forced")
#else
#define BROTLI_INLINE BROTLI_MAYBE_INLINE
#endif
#if BROTLI_GNUC_HAS_ATTRIBUTE(noinline, 4, 0, 0) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \
BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \
BROTLI_TI_VERSION_CHECK(8, 0, 0) || \
(BROTLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
#define BROTLI_NOINLINE __attribute__((__noinline__))
#elif BROTLI_MSVC_VERSION_CHECK(13, 10, 0)
#define BROTLI_NOINLINE __declspec(noinline)
#elif BROTLI_PGI_VERSION_CHECK(10, 2, 0)
#define BROTLI_NOINLINE _Pragma("noinline")
#elif BROTLI_TI_VERSION_CHECK(6, 0, 0) && defined(__cplusplus)
#define BROTLI_NOINLINE _Pragma("FUNC_CANNOT_INLINE;")
#elif BROTLI_IAR_VERSION_CHECK(8, 0, 0)
#define BROTLI_NOINLINE _Pragma("inline=never")
#else
#define BROTLI_NOINLINE
#endif
/* <<< <<< <<< end of hedley macros. */
#if BROTLI_GNUC_HAS_ATTRIBUTE(unused, 2, 7, 0) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
#define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE __attribute__ ((unused))
#else
#define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE
#endif
#if BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
#define BROTLI_ALIGNED(N) __attribute__((aligned(N)))
#else
#define BROTLI_ALIGNED(N)
#endif
#if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \
(defined(M_ARM) && (M_ARM == 7))
#define BROTLI_TARGET_ARMV7
#endif /* ARMv7 */
#if (defined(__ARM_ARCH) && (__ARM_ARCH == 8)) || \
defined(__aarch64__) || defined(__ARM64_ARCH_8__)
#define BROTLI_TARGET_ARMV8_ANY
#if defined(__ARM_32BIT_STATE)
#define BROTLI_TARGET_ARMV8_32
#elif defined(__ARM_64BIT_STATE)
#define BROTLI_TARGET_ARMV8_64
#endif
#endif /* ARMv8 */
#if defined(__ARM_NEON__) || defined(__ARM_NEON)
#define BROTLI_TARGET_NEON
#endif
#if defined(__i386) || defined(_M_IX86)
#define BROTLI_TARGET_X86
#endif
#if defined(__x86_64__) || defined(_M_X64)
#define BROTLI_TARGET_X64
#endif
#if defined(__PPC64__)
#define BROTLI_TARGET_POWERPC64
#endif
#if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64
#define BROTLI_TARGET_RISCV64
#endif
#if defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64)
#define BROTLI_TARGET_64_BITS 1
#else
#define BROTLI_TARGET_64_BITS 0
#endif
#if defined(BROTLI_BUILD_64_BIT)
#define BROTLI_64_BITS 1
#elif defined(BROTLI_BUILD_32_BIT)
#define BROTLI_64_BITS 0
#else
#define BROTLI_64_BITS BROTLI_TARGET_64_BITS
#endif
#if (BROTLI_64_BITS)
#define brotli_reg_t uint64_t
#else
#define brotli_reg_t uint32_t
#endif
#if defined(BROTLI_BUILD_BIG_ENDIAN)
#define BROTLI_BIG_ENDIAN 1
#elif defined(BROTLI_BUILD_LITTLE_ENDIAN)
#define BROTLI_LITTLE_ENDIAN 1
#elif defined(BROTLI_BUILD_ENDIAN_NEUTRAL)
/* Just break elif chain. */
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define BROTLI_LITTLE_ENDIAN 1
#elif defined(_WIN32) || defined(BROTLI_TARGET_X64)
/* Win32 & x64 can currently always be assumed to be little endian */
#define BROTLI_LITTLE_ENDIAN 1
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define BROTLI_BIG_ENDIAN 1
#elif defined(BROTLI_X_BYTE_ORDER)
#if BROTLI_X_BYTE_ORDER == BROTLI_X_LITTLE_ENDIAN
#define BROTLI_LITTLE_ENDIAN 1
#elif BROTLI_X_BYTE_ORDER == BROTLI_X_BIG_ENDIAN
#define BROTLI_BIG_ENDIAN 1
#endif
#endif /* BROTLI_X_BYTE_ORDER */
#if !defined(BROTLI_LITTLE_ENDIAN)
#define BROTLI_LITTLE_ENDIAN 0
#endif
#if !defined(BROTLI_BIG_ENDIAN)
#define BROTLI_BIG_ENDIAN 0
#endif
#if defined(BROTLI_X_BYTE_ORDER)
#undef BROTLI_X_BYTE_ORDER
#undef BROTLI_X_LITTLE_ENDIAN
#undef BROTLI_X_BIG_ENDIAN
#endif
#if defined(BROTLI_BUILD_NO_UNALIGNED_READ_FAST)
#define BROTLI_UNALIGNED_READ_FAST (!!0)
#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
defined(BROTLI_TARGET_RISCV64)
/* These targets are known to generate efficient code for unaligned reads
* (e.g. a single instruction, not multiple 1-byte loads, shifted and or'd
* together). */
#define BROTLI_UNALIGNED_READ_FAST (!!1)
#else
#define BROTLI_UNALIGNED_READ_FAST (!!0)
#endif
/* Portable unaligned memory access: read / write values via memcpy. */
static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) {
uint16_t t;
memcpy(&t, p, sizeof t);
return t;
}
static BROTLI_INLINE uint32_t BrotliUnalignedRead32(const void* p) {
uint32_t t;
memcpy(&t, p, sizeof t);
return t;
}
static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
uint64_t t;
memcpy(&t, p, sizeof t);
return t;
}
static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
memcpy(p, &v, sizeof v);
}
#if BROTLI_LITTLE_ENDIAN
/* Straight endianness. Just read / write values. */
#define BROTLI_UNALIGNED_LOAD16LE BrotliUnalignedRead16
#define BROTLI_UNALIGNED_LOAD32LE BrotliUnalignedRead32
#define BROTLI_UNALIGNED_LOAD64LE BrotliUnalignedRead64
#define BROTLI_UNALIGNED_STORE64LE BrotliUnalignedWrite64
#elif BROTLI_BIG_ENDIAN /* BROTLI_LITTLE_ENDIAN */
/* Explain compiler to byte-swap values. */
#define BROTLI_BSWAP16_(V) ((uint16_t)( \
(((V) & 0xFFU) << 8) | \
(((V) >> 8) & 0xFFU)))
static BROTLI_INLINE uint16_t BROTLI_UNALIGNED_LOAD16LE(const void* p) {
uint16_t value = BrotliUnalignedRead16(p);
return BROTLI_BSWAP16_(value);
}
#define BROTLI_BSWAP32_(V) ( \
(((V) & 0xFFU) << 24) | (((V) & 0xFF00U) << 8) | \
(((V) >> 8) & 0xFF00U) | (((V) >> 24) & 0xFFU))
static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32LE(const void* p) {
uint32_t value = BrotliUnalignedRead32(p);
return BROTLI_BSWAP32_(value);
}
#define BROTLI_BSWAP64_(V) ( \
(((V) & 0xFFU) << 56) | (((V) & 0xFF00U) << 40) | \
(((V) & 0xFF0000U) << 24) | (((V) & 0xFF000000U) << 8) | \
(((V) >> 8) & 0xFF000000U) | (((V) >> 24) & 0xFF0000U) | \
(((V) >> 40) & 0xFF00U) | (((V) >> 56) & 0xFFU))
static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void* p) {
uint64_t value = BrotliUnalignedRead64(p);
return BROTLI_BSWAP64_(value);
}
static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
uint64_t value = BROTLI_BSWAP64_(v);
BrotliUnalignedWrite64(p, value);
}
#else /* BROTLI_LITTLE_ENDIAN */
/* Read / store values byte-wise; hopefully compiler will understand. */
static BROTLI_INLINE uint16_t BROTLI_UNALIGNED_LOAD16LE(const void* p) {
const uint8_t* in = (const uint8_t*)p;
return (uint16_t)(in[0] | (in[1] << 8));
}
static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32LE(const void* p) {
const uint8_t* in = (const uint8_t*)p;
uint32_t value = (uint32_t)(in[0]);
value |= (uint32_t)(in[1]) << 8;
value |= (uint32_t)(in[2]) << 16;
value |= (uint32_t)(in[3]) << 24;
return value;
}
static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void* p) {
const uint8_t* in = (const uint8_t*)p;
uint64_t value = (uint64_t)(in[0]);
value |= (uint64_t)(in[1]) << 8;
value |= (uint64_t)(in[2]) << 16;
value |= (uint64_t)(in[3]) << 24;
value |= (uint64_t)(in[4]) << 32;
value |= (uint64_t)(in[5]) << 40;
value |= (uint64_t)(in[6]) << 48;
value |= (uint64_t)(in[7]) << 56;
return value;
}
static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
uint8_t* out = (uint8_t*)p;
out[0] = (uint8_t)v;
out[1] = (uint8_t)(v >> 8);
out[2] = (uint8_t)(v >> 16);
out[3] = (uint8_t)(v >> 24);
out[4] = (uint8_t)(v >> 32);
out[5] = (uint8_t)(v >> 40);
out[6] = (uint8_t)(v >> 48);
out[7] = (uint8_t)(v >> 56);
}
#endif /* BROTLI_LITTLE_ENDIAN */
static BROTLI_INLINE void* BROTLI_UNALIGNED_LOAD_PTR(const void* p) {
void* v;
memcpy(&v, p, sizeof(void*));
return v;
}
static BROTLI_INLINE void BROTLI_UNALIGNED_STORE_PTR(void* p, const void* v) {
memcpy(p, &v, sizeof(void*));
}
/* BROTLI_IS_CONSTANT macros returns true for compile-time constants. */
#if BROTLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
#define BROTLI_IS_CONSTANT(x) (!!__builtin_constant_p(x))
#else
#define BROTLI_IS_CONSTANT(x) (!!0)
#endif
#if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY)
#define BROTLI_HAS_UBFX (!!1)
#else
#define BROTLI_HAS_UBFX (!!0)
#endif
#if defined(BROTLI_ENABLE_LOG)
#define BROTLI_LOG(x) printf x
#else
#define BROTLI_LOG(x)
#endif
#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
#define BROTLI_DCHECK(x) assert(x)
static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) {
fprintf(stderr, "%s:%d (%s)\n", f, l, fn);
fflush(stderr);
}
#define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__)
#else
#define BROTLI_DCHECK(x)
#define BROTLI_DUMP() (void)(0)
#endif
/* BrotliRBit assumes brotli_reg_t fits native CPU register type. */
#if (BROTLI_64_BITS == BROTLI_TARGET_64_BITS)
/* TODO(eustas): add appropriate icc/sunpro/arm/ibm/ti checks. */
#if (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \
!defined(BROTLI_BUILD_NO_RBIT)
#if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY)
/* TODO(eustas): detect ARMv6T2 and enable this code for it. */
static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) {
brotli_reg_t output;
__asm__("rbit %0, %1\n" : "=r"(output) : "r"(input));
return output;
}
#define BROTLI_RBIT(x) BrotliRBit(x)
#endif /* armv7 / armv8 */
#endif /* gcc || clang */
#endif /* brotli_reg_t is native */
#if !defined(BROTLI_RBIT)
static BROTLI_INLINE void BrotliRBit(void) { /* Should break build if used. */ }
#endif /* BROTLI_RBIT */
#define BROTLI_REPEAT_4(X) {X; X; X; X;}
#define BROTLI_REPEAT_5(X) {X; X; X; X; X;}
#define BROTLI_REPEAT_6(X) {X; X; X; X; X; X;}
#define BROTLI_UNUSED(X) (void)(X)
#define BROTLI_MIN_MAX(T) \
static BROTLI_INLINE T brotli_min_ ## T (T a, T b) { return a < b ? a : b; } \
static BROTLI_INLINE T brotli_max_ ## T (T a, T b) { return a > b ? a : b; }
BROTLI_MIN_MAX(double) BROTLI_MIN_MAX(float) BROTLI_MIN_MAX(int)
BROTLI_MIN_MAX(size_t) BROTLI_MIN_MAX(uint32_t) BROTLI_MIN_MAX(uint8_t)
#undef BROTLI_MIN_MAX
#define BROTLI_MIN(T, A, B) (brotli_min_ ## T((A), (B)))
#define BROTLI_MAX(T, A, B) (brotli_max_ ## T((A), (B)))
#define BROTLI_SWAP(T, A, I, J) { \
T __brotli_swap_tmp = (A)[(I)]; \
(A)[(I)] = (A)[(J)]; \
(A)[(J)] = __brotli_swap_tmp; \
}
#if BROTLI_64_BITS
#if BROTLI_GNUC_HAS_BUILTIN(__builtin_ctzll, 3, 4, 0) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
#define BROTLI_TZCNT64 __builtin_ctzll
#elif BROTLI_MSVC_VERSION_CHECK(18, 0, 0)
#if defined(BROTLI_TARGET_X64)
#define BROTLI_TZCNT64 _tzcnt_u64
#else /* BROTLI_TARGET_X64 */
static BROTLI_INLINE uint32_t BrotliBsf64Msvc(uint64_t x) {
uint32_t lsb;
_BitScanForward64(&lsb, x);
return lsb;
}
#define BROTLI_TZCNT64 BrotliBsf64Msvc
#endif /* BROTLI_TARGET_X64 */
#endif /* __builtin_ctzll */
#endif /* BROTLI_64_BITS */
#if BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
#define BROTLI_BSR32(x) (31u ^ (uint32_t)__builtin_clz(x))
#elif BROTLI_MSVC_VERSION_CHECK(18, 0, 0)
static BROTLI_INLINE uint32_t BrotliBsr32Msvc(uint32_t x) {
unsigned long msb;
_BitScanReverse(&msb, x);
return (uint32_t)msb;
}
#define BROTLI_BSR32 BrotliBsr32Msvc
#endif /* __builtin_clz */
/* Default brotli_alloc_func */
BROTLI_COMMON_API void* BrotliDefaultAllocFunc(void* opaque, size_t size);
/* Default brotli_free_func */
BROTLI_COMMON_API void BrotliDefaultFreeFunc(void* opaque, void* address);
BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) {
BROTLI_UNUSED(&BrotliSuppressUnusedFunctions);
BROTLI_UNUSED(&BrotliUnalignedRead16);
BROTLI_UNUSED(&BrotliUnalignedRead32);
BROTLI_UNUSED(&BrotliUnalignedRead64);
BROTLI_UNUSED(&BrotliUnalignedWrite64);
BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD16LE);
BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD32LE);
BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD64LE);
BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE64LE);
BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD_PTR);
BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE_PTR);
BROTLI_UNUSED(&BrotliRBit);
BROTLI_UNUSED(&brotli_min_double);
BROTLI_UNUSED(&brotli_max_double);
BROTLI_UNUSED(&brotli_min_float);
BROTLI_UNUSED(&brotli_max_float);
BROTLI_UNUSED(&brotli_min_int);
BROTLI_UNUSED(&brotli_max_int);
BROTLI_UNUSED(&brotli_min_size_t);
BROTLI_UNUSED(&brotli_max_size_t);
BROTLI_UNUSED(&brotli_min_uint32_t);
BROTLI_UNUSED(&brotli_max_uint32_t);
BROTLI_UNUSED(&brotli_min_uint8_t);
BROTLI_UNUSED(&brotli_max_uint8_t);
BROTLI_UNUSED(&BrotliDefaultAllocFunc);
BROTLI_UNUSED(&BrotliDefaultFreeFunc);
#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
BROTLI_UNUSED(&BrotliDump);
#endif
}
#endif /* BROTLI_COMMON_PLATFORM_H_ */

View File

@ -1,515 +0,0 @@
/* Copyright 2017 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Shared Dictionary definition and utilities. */
#include <brotli/shared_dictionary.h>
#include <memory.h>
#include <stdlib.h> /* malloc, free */
#include <stdio.h>
#include "dictionary.h"
#include "platform.h"
#include "shared_dictionary_internal.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#define BROTLI_NUM_ENCODED_LENGTHS (SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH \
- SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH + 1)
/* Max allowed by spec */
#define BROTLI_MAX_SIZE_BITS 15u
/* Returns BROTLI_TRUE on success, BROTLI_FALSE on failure. */
static BROTLI_BOOL ReadBool(const uint8_t* encoded, size_t size, size_t* pos,
BROTLI_BOOL* result) {
uint8_t value;
size_t position = *pos;
if (position >= size) return BROTLI_FALSE; /* past file end */
value = encoded[position++];
if (value > 1) return BROTLI_FALSE; /* invalid bool */
*result = TO_BROTLI_BOOL(value);
*pos = position;
return BROTLI_TRUE; /* success */
}
/* Returns BROTLI_TRUE on success, BROTLI_FALSE on failure. */
static BROTLI_BOOL ReadUint8(const uint8_t* encoded, size_t size, size_t* pos,
uint8_t* result) {
size_t position = *pos;
if (position + sizeof(uint8_t) > size) return BROTLI_FALSE;
*result = encoded[position++];
*pos = position;
return BROTLI_TRUE;
}
/* Returns BROTLI_TRUE on success, BROTLI_FALSE on failure. */
static BROTLI_BOOL ReadUint16(const uint8_t* encoded, size_t size, size_t* pos,
uint16_t* result) {
size_t position = *pos;
if (position + sizeof(uint16_t) > size) return BROTLI_FALSE;
*result = BROTLI_UNALIGNED_LOAD16LE(&encoded[position]);
position += 2;
*pos = position;
return BROTLI_TRUE;
}
/* Reads a varint into a uint32_t, and returns error if it's too large */
/* Returns BROTLI_TRUE on success, BROTLI_FALSE on failure. */
static BROTLI_BOOL ReadVarint32(const uint8_t* encoded, size_t size,
size_t* pos, uint32_t* result) {
int num = 0;
uint8_t byte;
*result = 0;
for (;;) {
if (*pos >= size) return BROTLI_FALSE;
byte = encoded[(*pos)++];
if (num == 4 && byte > 15) return BROTLI_FALSE;
*result |= (uint32_t)(byte & 127) << (num * 7);
if (byte < 128) return BROTLI_TRUE;
num++;
}
}
/* Returns the total length of word list. */
static size_t BrotliSizeBitsToOffsets(const uint8_t* size_bits_by_length,
uint32_t* offsets_by_length) {
uint32_t pos = 0;
uint32_t i;
for (i = 0; i <= SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH; i++) {
offsets_by_length[i] = pos;
if (size_bits_by_length[i] != 0) {
pos += i << size_bits_by_length[i];
}
}
return pos;
}
static BROTLI_BOOL ParseWordList(size_t size, const uint8_t* encoded,
size_t* pos, BrotliDictionary* out) {
size_t offset;
size_t i;
size_t position = *pos;
if (position + BROTLI_NUM_ENCODED_LENGTHS > size) {
return BROTLI_FALSE;
}
memset(out->size_bits_by_length, 0, SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH);
memcpy(out->size_bits_by_length + SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH,
&encoded[position], BROTLI_NUM_ENCODED_LENGTHS);
for (i = SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH;
i <= SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH; i++) {
if (out->size_bits_by_length[i] > BROTLI_MAX_SIZE_BITS) {
return BROTLI_FALSE;
}
}
position += BROTLI_NUM_ENCODED_LENGTHS;
offset = BrotliSizeBitsToOffsets(
out->size_bits_by_length, out->offsets_by_length);
out->data = &encoded[position];
out->data_size = offset;
position += offset;
if (position > size) return BROTLI_FALSE;
*pos = position;
return BROTLI_TRUE;
}
/* Computes the cutOffTransforms of a BrotliTransforms which already has the
transforms data correctly filled in. */
static void ComputeCutoffTransforms(BrotliTransforms* transforms) {
uint32_t i;
for (i = 0; i < BROTLI_TRANSFORMS_MAX_CUT_OFF + 1; i++) {
transforms->cutOffTransforms[i] = -1;
}
for (i = 0; i < transforms->num_transforms; i++) {
const uint8_t* prefix = BROTLI_TRANSFORM_PREFIX(transforms, i);
uint8_t type = BROTLI_TRANSFORM_TYPE(transforms, i);
const uint8_t* suffix = BROTLI_TRANSFORM_SUFFIX(transforms, i);
if (type <= BROTLI_TRANSFORM_OMIT_LAST_9 && *prefix == 0 && *suffix == 0 &&
transforms->cutOffTransforms[type] == -1) {
transforms->cutOffTransforms[type] = (int16_t)i;
}
}
}
static BROTLI_BOOL ParsePrefixSuffixTable(size_t size, const uint8_t* encoded,
size_t* pos, BrotliTransforms* out, uint16_t* out_table,
size_t* out_table_size) {
size_t position = *pos;
size_t offset = 0;
size_t stringlet_count = 0; /* NUM_PREFIX_SUFFIX */
size_t data_length = 0;
/* PREFIX_SUFFIX_LENGTH */
if (!ReadUint16(encoded, size, &position, &out->prefix_suffix_size)) {
return BROTLI_FALSE;
}
data_length = out->prefix_suffix_size;
/* Must at least have space for null terminator. */
if (data_length < 1) return BROTLI_FALSE;
out->prefix_suffix = &encoded[position];
if (position + data_length >= size) return BROTLI_FALSE;
while (BROTLI_TRUE) {
/* STRING_LENGTH */
size_t stringlet_len = encoded[position + offset];
out_table[stringlet_count] = (uint16_t)offset;
stringlet_count++;
offset++;
if (stringlet_len == 0) {
if (offset == data_length) {
break;
} else {
return BROTLI_FALSE;
}
}
if (stringlet_count > 255) return BROTLI_FALSE;
offset += stringlet_len;
if (offset >= data_length) return BROTLI_FALSE;
}
position += data_length;
*pos = position;
*out_table_size = (uint16_t)stringlet_count;
return BROTLI_TRUE;
}
static BROTLI_BOOL ParseTransformsList(size_t size, const uint8_t* encoded,
size_t* pos, BrotliTransforms* out, uint16_t* prefix_suffix_table,
size_t* prefix_suffix_count) {
uint32_t i;
BROTLI_BOOL has_params = BROTLI_FALSE;
BROTLI_BOOL prefix_suffix_ok = BROTLI_FALSE;
size_t position = *pos;
size_t stringlet_cnt = 0;
if (position >= size) return BROTLI_FALSE;
prefix_suffix_ok = ParsePrefixSuffixTable(
size, encoded, &position, out, prefix_suffix_table, &stringlet_cnt);
if (!prefix_suffix_ok) return BROTLI_FALSE;
out->prefix_suffix_map = prefix_suffix_table;
*prefix_suffix_count = stringlet_cnt;
out->num_transforms = encoded[position++];
out->transforms = &encoded[position];
position += (size_t)out->num_transforms * 3;
if (position > size) return BROTLI_FALSE;
/* Check for errors and read extra parameters. */
for (i = 0; i < out->num_transforms; i++) {
uint8_t prefix_id = BROTLI_TRANSFORM_PREFIX_ID(out, i);
uint8_t type = BROTLI_TRANSFORM_TYPE(out, i);
uint8_t suffix_id = BROTLI_TRANSFORM_SUFFIX_ID(out, i);
if (prefix_id >= stringlet_cnt) return BROTLI_FALSE;
if (type >= BROTLI_NUM_TRANSFORM_TYPES) return BROTLI_FALSE;
if (suffix_id >= stringlet_cnt) return BROTLI_FALSE;
if (type == BROTLI_TRANSFORM_SHIFT_FIRST ||
type == BROTLI_TRANSFORM_SHIFT_ALL) {
has_params = BROTLI_TRUE;
}
}
if (has_params) {
out->params = &encoded[position];
position += (size_t)out->num_transforms * 2;
if (position > size) return BROTLI_FALSE;
for (i = 0; i < out->num_transforms; i++) {
uint8_t type = BROTLI_TRANSFORM_TYPE(out, i);
if (type != BROTLI_TRANSFORM_SHIFT_FIRST &&
type != BROTLI_TRANSFORM_SHIFT_ALL) {
if (out->params[i * 2] != 0 || out->params[i * 2 + 1] != 0) {
return BROTLI_FALSE;
}
}
}
} else {
out->params = NULL;
}
ComputeCutoffTransforms(out);
*pos = position;
return BROTLI_TRUE;
}
static BROTLI_BOOL DryParseDictionary(const uint8_t* encoded,
size_t size, uint32_t* num_prefix, BROTLI_BOOL* is_custom_static_dict) {
size_t pos = 0;
uint32_t chunk_size = 0;
uint8_t num_word_lists;
uint8_t num_transform_lists;
*is_custom_static_dict = BROTLI_FALSE;
*num_prefix = 0;
/* Skip magic header bytes. */
pos += 2;
/* LZ77_DICTIONARY_LENGTH */
if (!ReadVarint32(encoded, size, &pos, &chunk_size)) return BROTLI_FALSE;
if (chunk_size != 0) {
/* This limitation is not specified but the 32-bit Brotli decoder for now */
if (chunk_size > 1073741823) return BROTLI_FALSE;
*num_prefix = 1;
if (pos + chunk_size > size) return BROTLI_FALSE;
pos += chunk_size;
}
if (!ReadUint8(encoded, size, &pos, &num_word_lists)) {
return BROTLI_FALSE;
}
if (!ReadUint8(encoded, size, &pos, &num_transform_lists)) {
return BROTLI_FALSE;
}
if (num_word_lists > 0 || num_transform_lists > 0) {
*is_custom_static_dict = BROTLI_TRUE;
}
return BROTLI_TRUE;
}
static BROTLI_BOOL ParseDictionary(const uint8_t* encoded, size_t size,
BrotliSharedDictionary* dict) {
uint32_t i;
size_t pos = 0;
uint32_t chunk_size = 0;
size_t total_prefix_suffix_count = 0;
size_t trasform_list_start[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS];
uint16_t temporary_prefix_suffix_table[256];
/* Skip magic header bytes. */
pos += 2;
/* LZ77_DICTIONARY_LENGTH */
if (!ReadVarint32(encoded, size, &pos, &chunk_size)) return BROTLI_FALSE;
if (chunk_size != 0) {
if (pos + chunk_size > size) return BROTLI_FALSE;
dict->prefix_size[dict->num_prefix] = chunk_size;
dict->prefix[dict->num_prefix] = &encoded[pos];
dict->num_prefix++;
/* LZ77_DICTIONARY_LENGTH bytes. */
pos += chunk_size;
}
/* NUM_WORD_LISTS */
if (!ReadUint8(encoded, size, &pos, &dict->num_word_lists)) {
return BROTLI_FALSE;
}
if (dict->num_word_lists > SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS) {
return BROTLI_FALSE;
}
if (dict->num_word_lists != 0) {
dict->words_instances = (BrotliDictionary*)dict->alloc_func(
dict->memory_manager_opaque,
dict->num_word_lists * sizeof(*dict->words_instances));
if (!dict->words_instances) return BROTLI_FALSE; /* OOM */
}
for (i = 0; i < dict->num_word_lists; i++) {
if (!ParseWordList(size, encoded, &pos, &dict->words_instances[i])) {
return BROTLI_FALSE;
}
}
/* NUM_TRANSFORM_LISTS */
if (!ReadUint8(encoded, size, &pos, &dict->num_transform_lists)) {
return BROTLI_FALSE;
}
if (dict->num_transform_lists > SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS) {
return BROTLI_FALSE;
}
if (dict->num_transform_lists != 0) {
dict->transforms_instances = (BrotliTransforms*)dict->alloc_func(
dict->memory_manager_opaque,
dict->num_transform_lists * sizeof(*dict->transforms_instances));
if (!dict->transforms_instances) return BROTLI_FALSE; /* OOM */
}
for (i = 0; i < dict->num_transform_lists; i++) {
BROTLI_BOOL ok = BROTLI_FALSE;
size_t prefix_suffix_count = 0;
trasform_list_start[i] = pos;
dict->transforms_instances[i].prefix_suffix_map =
temporary_prefix_suffix_table;
ok = ParseTransformsList(
size, encoded, &pos, &dict->transforms_instances[i],
temporary_prefix_suffix_table, &prefix_suffix_count);
if (!ok) return BROTLI_FALSE;
total_prefix_suffix_count += prefix_suffix_count;
}
if (total_prefix_suffix_count != 0) {
dict->prefix_suffix_maps = (uint16_t*)dict->alloc_func(
dict->memory_manager_opaque,
total_prefix_suffix_count * sizeof(*dict->prefix_suffix_maps));
if (!dict->prefix_suffix_maps) return BROTLI_FALSE; /* OOM */
}
total_prefix_suffix_count = 0;
for (i = 0; i < dict->num_transform_lists; i++) {
size_t prefix_suffix_count = 0;
size_t position = trasform_list_start[i];
uint16_t* prefix_suffix_map =
&dict->prefix_suffix_maps[total_prefix_suffix_count];
BROTLI_BOOL ok = ParsePrefixSuffixTable(
size, encoded, &position, &dict->transforms_instances[i],
prefix_suffix_map, &prefix_suffix_count);
if (!ok) return BROTLI_FALSE;
dict->transforms_instances[i].prefix_suffix_map = prefix_suffix_map;
total_prefix_suffix_count += prefix_suffix_count;
}
if (dict->num_word_lists != 0 || dict->num_transform_lists != 0) {
if (!ReadUint8(encoded, size, &pos, &dict->num_dictionaries)) {
return BROTLI_FALSE;
}
if (dict->num_dictionaries == 0 ||
dict->num_dictionaries > SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS) {
return BROTLI_FALSE;
}
for (i = 0; i < dict->num_dictionaries; i++) {
uint8_t words_index;
uint8_t transforms_index;
if (!ReadUint8(encoded, size, &pos, &words_index)) {
return BROTLI_FALSE;
}
if (words_index > dict->num_word_lists) return BROTLI_FALSE;
if (!ReadUint8(encoded, size, &pos, &transforms_index)) {
return BROTLI_FALSE;
}
if (transforms_index > dict->num_transform_lists) return BROTLI_FALSE;
dict->words[i] = words_index == dict->num_word_lists ?
BrotliGetDictionary() : &dict->words_instances[words_index];
dict->transforms[i] = transforms_index == dict->num_transform_lists ?
BrotliGetTransforms(): &dict->transforms_instances[transforms_index];
}
/* CONTEXT_ENABLED */
if (!ReadBool(encoded, size, &pos, &dict->context_based)) {
return BROTLI_FALSE;
}
/* CONTEXT_MAP */
if (dict->context_based) {
for (i = 0; i < SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS; i++) {
if (!ReadUint8(encoded, size, &pos, &dict->context_map[i])) {
return BROTLI_FALSE;
}
if (dict->context_map[i] >= dict->num_dictionaries) {
return BROTLI_FALSE;
}
}
}
} else {
dict->context_based = BROTLI_FALSE;
dict->num_dictionaries = 1;
dict->words[0] = BrotliGetDictionary();
dict->transforms[0] = BrotliGetTransforms();
}
return BROTLI_TRUE;
}
/* Decodes shared dictionary and verifies correctness.
Returns BROTLI_TRUE if dictionary is valid, BROTLI_FALSE otherwise.
The BrotliSharedDictionary must already have been initialized. If the
BrotliSharedDictionary already contains data, compound dictionaries
will be appended, but an error will be returned if it already has
custom words or transforms.
TODO(lode): link to RFC for shared brotli once published. */
static BROTLI_BOOL DecodeSharedDictionary(
const uint8_t* encoded, size_t size, BrotliSharedDictionary* dict) {
uint32_t num_prefix = 0;
BROTLI_BOOL is_custom_static_dict = BROTLI_FALSE;
BROTLI_BOOL has_custom_static_dict =
dict->num_word_lists > 0 || dict->num_transform_lists > 0;
/* Check magic header bytes. */
if (size < 2) return BROTLI_FALSE;
if (encoded[0] != 0x91 || encoded[1] != 0) return BROTLI_FALSE;
if (!DryParseDictionary(encoded, size, &num_prefix, &is_custom_static_dict)) {
return BROTLI_FALSE;
}
if (num_prefix + dict->num_prefix > SHARED_BROTLI_MAX_COMPOUND_DICTS) {
return BROTLI_FALSE;
}
/* Cannot combine different static dictionaries, only prefix dictionaries */
if (has_custom_static_dict && is_custom_static_dict) return BROTLI_FALSE;
return ParseDictionary(encoded, size, dict);
}
void BrotliSharedDictionaryDestroyInstance(
BrotliSharedDictionary* dict) {
if (!dict) {
return;
} else {
brotli_free_func free_func = dict->free_func;
void* opaque = dict->memory_manager_opaque;
/* Cleanup. */
free_func(opaque, dict->words_instances);
free_func(opaque, dict->transforms_instances);
free_func(opaque, dict->prefix_suffix_maps);
/* Self-destruction. */
free_func(opaque, dict);
}
}
BROTLI_BOOL BrotliSharedDictionaryAttach(
BrotliSharedDictionary* dict, BrotliSharedDictionaryType type,
size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]) {
if (!dict) {
return BROTLI_FALSE;
}
if (type == BROTLI_SHARED_DICTIONARY_SERIALIZED) {
return DecodeSharedDictionary(data, data_size, dict);
} else if (type == BROTLI_SHARED_DICTIONARY_RAW) {
if (dict->num_prefix >= SHARED_BROTLI_MAX_COMPOUND_DICTS) {
return BROTLI_FALSE;
}
dict->prefix_size[dict->num_prefix] = data_size;
dict->prefix[dict->num_prefix] = data;
dict->num_prefix++;
return BROTLI_TRUE;
} else {
return BROTLI_FALSE;
}
}
BrotliSharedDictionary* BrotliSharedDictionaryCreateInstance(
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
BrotliSharedDictionary* dict = 0;
if (!alloc_func && !free_func) {
dict = (BrotliSharedDictionary*)malloc(sizeof(BrotliSharedDictionary));
} else if (alloc_func && free_func) {
dict = (BrotliSharedDictionary*)alloc_func(
opaque, sizeof(BrotliSharedDictionary));
}
if (dict == 0) {
return 0;
}
/* TODO(eustas): explicitly initialize all the fields? */
memset(dict, 0, sizeof(BrotliSharedDictionary));
dict->context_based = BROTLI_FALSE;
dict->num_dictionaries = 1;
dict->num_word_lists = 0;
dict->num_transform_lists = 0;
dict->words[0] = BrotliGetDictionary();
dict->transforms[0] = BrotliGetTransforms();
dict->alloc_func = alloc_func ? alloc_func : BrotliDefaultAllocFunc;
dict->free_func = free_func ? free_func : BrotliDefaultFreeFunc;
dict->memory_manager_opaque = opaque;
return dict;
}
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif

View File

@ -1,75 +0,0 @@
/* Copyright 2017 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* (Transparent) Shared Dictionary definition. */
#ifndef BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_
#define BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_
#include <brotli/shared_dictionary.h>
#include <brotli/types.h>
#include "dictionary.h"
#include "transform.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
struct BrotliSharedDictionaryStruct {
/* LZ77 prefixes (compound dictionary). */
uint32_t num_prefix; /* max SHARED_BROTLI_MAX_COMPOUND_DICTS */
size_t prefix_size[SHARED_BROTLI_MAX_COMPOUND_DICTS];
const uint8_t* prefix[SHARED_BROTLI_MAX_COMPOUND_DICTS];
/* If set, the context map is used to select word and transform list from 64
contexts, if not set, the context map is not used and only words[0] and
transforms[0] are to be used. */
BROTLI_BOOL context_based;
uint8_t context_map[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS];
/* Amount of word_list+transform_list combinations. */
uint8_t num_dictionaries;
/* Must use num_dictionaries values. */
const BrotliDictionary* words[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS];
/* Must use num_dictionaries values. */
const BrotliTransforms* transforms[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS];
/* Amount of custom word lists. May be 0 if only Brotli's built-in is used */
uint8_t num_word_lists;
/* Contents of the custom words lists. Must be NULL if num_word_lists is 0. */
BrotliDictionary* words_instances;
/* Amount of custom transform lists. May be 0 if only Brotli's built-in is
used */
uint8_t num_transform_lists;
/* Contents of the custom transform lists. Must be NULL if num_transform_lists
is 0. */
BrotliTransforms* transforms_instances;
/* Concatenated prefix_suffix_maps of the custom transform lists. Must be NULL
if num_transform_lists is 0. */
uint16_t* prefix_suffix_maps;
/* Memory management */
brotli_alloc_func alloc_func;
brotli_free_func free_func;
void* memory_manager_opaque;
};
typedef struct BrotliSharedDictionaryStruct BrotliSharedDictionaryInternal;
#define BrotliSharedDictionary BrotliSharedDictionaryInternal
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_ */

View File

@ -1,291 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
#include "transform.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
/* RFC 7932 transforms string data */
static const char kPrefixSuffix[217] =
"\1 \2, \10 of the \4 of \2s \1.\5 and \4 "
/* 0x _0 _2 __5 _E _3 _6 _8 _E */
"in \1\"\4 to \2\">\1\n\2. \1]\5 for \3 a \6 "
/* 2x _3_ _5 _A_ _D_ _F _2 _4 _A _E */
"that \1\'\6 with \6 from \4 by \1(\6. T"
/* 4x _5_ _7 _E _5 _A _C */
"he \4 on \4 as \4 is \4ing \2\n\t\1:\3ed "
/* 6x _3 _8 _D _2 _7_ _ _A _C */
"\2=\"\4 at \3ly \1,\2=\'\5.com/\7. This \5"
/* 8x _0 _ _3 _8 _C _E _ _1 _7 _F */
" not \3er \3al \4ful \4ive \5less \4es"
/* Ax _5 _9 _D _2 _7 _D */
"t \4ize \2\xc2\xa0\4ous \5 the \2e "; /* \0 - implicit trailing zero. */
/* Cx _2 _7___ ___ _A _F _5 _8 */
static const uint16_t kPrefixSuffixMap[50] = {
0x00, 0x02, 0x05, 0x0E, 0x13, 0x16, 0x18, 0x1E, 0x23, 0x25,
0x2A, 0x2D, 0x2F, 0x32, 0x34, 0x3A, 0x3E, 0x45, 0x47, 0x4E,
0x55, 0x5A, 0x5C, 0x63, 0x68, 0x6D, 0x72, 0x77, 0x7A, 0x7C,
0x80, 0x83, 0x88, 0x8C, 0x8E, 0x91, 0x97, 0x9F, 0xA5, 0xA9,
0xAD, 0xB2, 0xB7, 0xBD, 0xC2, 0xC7, 0xCA, 0xCF, 0xD5, 0xD8
};
/* RFC 7932 transforms */
static const uint8_t kTransformsData[] = {
49, BROTLI_TRANSFORM_IDENTITY, 49,
49, BROTLI_TRANSFORM_IDENTITY, 0,
0, BROTLI_TRANSFORM_IDENTITY, 0,
49, BROTLI_TRANSFORM_OMIT_FIRST_1, 49,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 0,
49, BROTLI_TRANSFORM_IDENTITY, 47,
0, BROTLI_TRANSFORM_IDENTITY, 49,
4, BROTLI_TRANSFORM_IDENTITY, 0,
49, BROTLI_TRANSFORM_IDENTITY, 3,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 49,
49, BROTLI_TRANSFORM_IDENTITY, 6,
49, BROTLI_TRANSFORM_OMIT_FIRST_2, 49,
49, BROTLI_TRANSFORM_OMIT_LAST_1, 49,
1, BROTLI_TRANSFORM_IDENTITY, 0,
49, BROTLI_TRANSFORM_IDENTITY, 1,
0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 0,
49, BROTLI_TRANSFORM_IDENTITY, 7,
49, BROTLI_TRANSFORM_IDENTITY, 9,
48, BROTLI_TRANSFORM_IDENTITY, 0,
49, BROTLI_TRANSFORM_IDENTITY, 8,
49, BROTLI_TRANSFORM_IDENTITY, 5,
49, BROTLI_TRANSFORM_IDENTITY, 10,
49, BROTLI_TRANSFORM_IDENTITY, 11,
49, BROTLI_TRANSFORM_OMIT_LAST_3, 49,
49, BROTLI_TRANSFORM_IDENTITY, 13,
49, BROTLI_TRANSFORM_IDENTITY, 14,
49, BROTLI_TRANSFORM_OMIT_FIRST_3, 49,
49, BROTLI_TRANSFORM_OMIT_LAST_2, 49,
49, BROTLI_TRANSFORM_IDENTITY, 15,
49, BROTLI_TRANSFORM_IDENTITY, 16,
0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 49,
49, BROTLI_TRANSFORM_IDENTITY, 12,
5, BROTLI_TRANSFORM_IDENTITY, 49,
0, BROTLI_TRANSFORM_IDENTITY, 1,
49, BROTLI_TRANSFORM_OMIT_FIRST_4, 49,
49, BROTLI_TRANSFORM_IDENTITY, 18,
49, BROTLI_TRANSFORM_IDENTITY, 17,
49, BROTLI_TRANSFORM_IDENTITY, 19,
49, BROTLI_TRANSFORM_IDENTITY, 20,
49, BROTLI_TRANSFORM_OMIT_FIRST_5, 49,
49, BROTLI_TRANSFORM_OMIT_FIRST_6, 49,
47, BROTLI_TRANSFORM_IDENTITY, 49,
49, BROTLI_TRANSFORM_OMIT_LAST_4, 49,
49, BROTLI_TRANSFORM_IDENTITY, 22,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 49,
49, BROTLI_TRANSFORM_IDENTITY, 23,
49, BROTLI_TRANSFORM_IDENTITY, 24,
49, BROTLI_TRANSFORM_IDENTITY, 25,
49, BROTLI_TRANSFORM_OMIT_LAST_7, 49,
49, BROTLI_TRANSFORM_OMIT_LAST_1, 26,
49, BROTLI_TRANSFORM_IDENTITY, 27,
49, BROTLI_TRANSFORM_IDENTITY, 28,
0, BROTLI_TRANSFORM_IDENTITY, 12,
49, BROTLI_TRANSFORM_IDENTITY, 29,
49, BROTLI_TRANSFORM_OMIT_FIRST_9, 49,
49, BROTLI_TRANSFORM_OMIT_FIRST_7, 49,
49, BROTLI_TRANSFORM_OMIT_LAST_6, 49,
49, BROTLI_TRANSFORM_IDENTITY, 21,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 1,
49, BROTLI_TRANSFORM_OMIT_LAST_8, 49,
49, BROTLI_TRANSFORM_IDENTITY, 31,
49, BROTLI_TRANSFORM_IDENTITY, 32,
47, BROTLI_TRANSFORM_IDENTITY, 3,
49, BROTLI_TRANSFORM_OMIT_LAST_5, 49,
49, BROTLI_TRANSFORM_OMIT_LAST_9, 49,
0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 1,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 8,
5, BROTLI_TRANSFORM_IDENTITY, 21,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 0,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 10,
49, BROTLI_TRANSFORM_IDENTITY, 30,
0, BROTLI_TRANSFORM_IDENTITY, 5,
35, BROTLI_TRANSFORM_IDENTITY, 49,
47, BROTLI_TRANSFORM_IDENTITY, 2,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 17,
49, BROTLI_TRANSFORM_IDENTITY, 36,
49, BROTLI_TRANSFORM_IDENTITY, 33,
5, BROTLI_TRANSFORM_IDENTITY, 0,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 21,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 5,
49, BROTLI_TRANSFORM_IDENTITY, 37,
0, BROTLI_TRANSFORM_IDENTITY, 30,
49, BROTLI_TRANSFORM_IDENTITY, 38,
0, BROTLI_TRANSFORM_UPPERCASE_ALL, 0,
49, BROTLI_TRANSFORM_IDENTITY, 39,
0, BROTLI_TRANSFORM_UPPERCASE_ALL, 49,
49, BROTLI_TRANSFORM_IDENTITY, 34,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 8,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 12,
0, BROTLI_TRANSFORM_IDENTITY, 21,
49, BROTLI_TRANSFORM_IDENTITY, 40,
0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 12,
49, BROTLI_TRANSFORM_IDENTITY, 41,
49, BROTLI_TRANSFORM_IDENTITY, 42,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 17,
49, BROTLI_TRANSFORM_IDENTITY, 43,
0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 5,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 10,
0, BROTLI_TRANSFORM_IDENTITY, 34,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 33,
49, BROTLI_TRANSFORM_IDENTITY, 44,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 5,
45, BROTLI_TRANSFORM_IDENTITY, 49,
0, BROTLI_TRANSFORM_IDENTITY, 33,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 30,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 30,
49, BROTLI_TRANSFORM_IDENTITY, 46,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 1,
49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 34,
0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 33,
0, BROTLI_TRANSFORM_UPPERCASE_ALL, 30,
0, BROTLI_TRANSFORM_UPPERCASE_ALL, 1,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 33,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 21,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 12,
0, BROTLI_TRANSFORM_UPPERCASE_ALL, 5,
49, BROTLI_TRANSFORM_UPPERCASE_ALL, 34,
0, BROTLI_TRANSFORM_UPPERCASE_ALL, 12,
0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 30,
0, BROTLI_TRANSFORM_UPPERCASE_ALL, 34,
0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 34,
};
static const BrotliTransforms kBrotliTransforms = {
sizeof(kPrefixSuffix),
(const uint8_t*)kPrefixSuffix,
kPrefixSuffixMap,
sizeof(kTransformsData) / (3 * sizeof(kTransformsData[0])),
kTransformsData,
NULL, /* no extra parameters */
{0, 12, 27, 23, 42, 63, 56, 48, 59, 64}
};
const BrotliTransforms* BrotliGetTransforms(void) {
return &kBrotliTransforms;
}
static int ToUpperCase(uint8_t* p) {
if (p[0] < 0xC0) {
if (p[0] >= 'a' && p[0] <= 'z') {
p[0] ^= 32;
}
return 1;
}
/* An overly simplified uppercasing model for UTF-8. */
if (p[0] < 0xE0) {
p[1] ^= 32;
return 2;
}
/* An arbitrary transform for three byte characters. */
p[2] ^= 5;
return 3;
}
static int Shift(uint8_t* word, int word_len, uint16_t parameter) {
/* Limited sign extension: scalar < (1 << 24). */
uint32_t scalar =
(parameter & 0x7FFFu) + (0x1000000u - (parameter & 0x8000u));
if (word[0] < 0x80) {
/* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */
scalar += (uint32_t)word[0];
word[0] = (uint8_t)(scalar & 0x7Fu);
return 1;
} else if (word[0] < 0xC0) {
/* Continuation / 10AAAAAA. */
return 1;
} else if (word[0] < 0xE0) {
/* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */
if (word_len < 2) return 1;
scalar += (uint32_t)((word[1] & 0x3Fu) | ((word[0] & 0x1Fu) << 6u));
word[0] = (uint8_t)(0xC0 | ((scalar >> 6u) & 0x1F));
word[1] = (uint8_t)((word[1] & 0xC0) | (scalar & 0x3F));
return 2;
} else if (word[0] < 0xF0) {
/* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */
if (word_len < 3) return word_len;
scalar += (uint32_t)((word[2] & 0x3Fu) | ((word[1] & 0x3Fu) << 6u) |
((word[0] & 0x0Fu) << 12u));
word[0] = (uint8_t)(0xE0 | ((scalar >> 12u) & 0x0F));
word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 6u) & 0x3F));
word[2] = (uint8_t)((word[2] & 0xC0) | (scalar & 0x3F));
return 3;
} else if (word[0] < 0xF8) {
/* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */
if (word_len < 4) return word_len;
scalar += (uint32_t)((word[3] & 0x3Fu) | ((word[2] & 0x3Fu) << 6u) |
((word[1] & 0x3Fu) << 12u) | ((word[0] & 0x07u) << 18u));
word[0] = (uint8_t)(0xF0 | ((scalar >> 18u) & 0x07));
word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 12u) & 0x3F));
word[2] = (uint8_t)((word[2] & 0xC0) | ((scalar >> 6u) & 0x3F));
word[3] = (uint8_t)((word[3] & 0xC0) | (scalar & 0x3F));
return 4;
}
return 1;
}
int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len,
const BrotliTransforms* transforms, int transform_idx) {
int idx = 0;
const uint8_t* prefix = BROTLI_TRANSFORM_PREFIX(transforms, transform_idx);
uint8_t type = BROTLI_TRANSFORM_TYPE(transforms, transform_idx);
const uint8_t* suffix = BROTLI_TRANSFORM_SUFFIX(transforms, transform_idx);
{
int prefix_len = *prefix++;
while (prefix_len--) { dst[idx++] = *prefix++; }
}
{
const int t = type;
int i = 0;
if (t <= BROTLI_TRANSFORM_OMIT_LAST_9) {
len -= t;
} else if (t >= BROTLI_TRANSFORM_OMIT_FIRST_1
&& t <= BROTLI_TRANSFORM_OMIT_FIRST_9) {
int skip = t - (BROTLI_TRANSFORM_OMIT_FIRST_1 - 1);
word += skip;
len -= skip;
}
while (i < len) { dst[idx++] = word[i++]; }
if (t == BROTLI_TRANSFORM_UPPERCASE_FIRST) {
ToUpperCase(&dst[idx - len]);
} else if (t == BROTLI_TRANSFORM_UPPERCASE_ALL) {
uint8_t* uppercase = &dst[idx - len];
while (len > 0) {
int step = ToUpperCase(uppercase);
uppercase += step;
len -= step;
}
} else if (t == BROTLI_TRANSFORM_SHIFT_FIRST) {
uint16_t param = (uint16_t)(transforms->params[transform_idx * 2]
+ (transforms->params[transform_idx * 2 + 1] << 8u));
Shift(&dst[idx - len], len, param);
} else if (t == BROTLI_TRANSFORM_SHIFT_ALL) {
uint16_t param = (uint16_t)(transforms->params[transform_idx * 2]
+ (transforms->params[transform_idx * 2 + 1] << 8u));
uint8_t* shift = &dst[idx - len];
while (len > 0) {
int step = Shift(shift, len, param);
shift += step;
len -= step;
}
}
}
{
int suffix_len = *suffix++;
while (suffix_len--) { dst[idx++] = *suffix++; }
return idx;
}
}
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif

View File

@ -1,85 +0,0 @@
/* transforms is a part of ABI, but not API.
It means that there are some functions that are supposed to be in "common"
library, but header itself is not placed into include/brotli. This way,
aforementioned functions will be available only to brotli internals.
*/
#ifndef BROTLI_COMMON_TRANSFORM_H_
#define BROTLI_COMMON_TRANSFORM_H_
#include <brotli/port.h>
#include <brotli/types.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
enum BrotliWordTransformType {
BROTLI_TRANSFORM_IDENTITY = 0,
BROTLI_TRANSFORM_OMIT_LAST_1 = 1,
BROTLI_TRANSFORM_OMIT_LAST_2 = 2,
BROTLI_TRANSFORM_OMIT_LAST_3 = 3,
BROTLI_TRANSFORM_OMIT_LAST_4 = 4,
BROTLI_TRANSFORM_OMIT_LAST_5 = 5,
BROTLI_TRANSFORM_OMIT_LAST_6 = 6,
BROTLI_TRANSFORM_OMIT_LAST_7 = 7,
BROTLI_TRANSFORM_OMIT_LAST_8 = 8,
BROTLI_TRANSFORM_OMIT_LAST_9 = 9,
BROTLI_TRANSFORM_UPPERCASE_FIRST = 10,
BROTLI_TRANSFORM_UPPERCASE_ALL = 11,
BROTLI_TRANSFORM_OMIT_FIRST_1 = 12,
BROTLI_TRANSFORM_OMIT_FIRST_2 = 13,
BROTLI_TRANSFORM_OMIT_FIRST_3 = 14,
BROTLI_TRANSFORM_OMIT_FIRST_4 = 15,
BROTLI_TRANSFORM_OMIT_FIRST_5 = 16,
BROTLI_TRANSFORM_OMIT_FIRST_6 = 17,
BROTLI_TRANSFORM_OMIT_FIRST_7 = 18,
BROTLI_TRANSFORM_OMIT_FIRST_8 = 19,
BROTLI_TRANSFORM_OMIT_FIRST_9 = 20,
BROTLI_TRANSFORM_SHIFT_FIRST = 21,
BROTLI_TRANSFORM_SHIFT_ALL = 22,
BROTLI_NUM_TRANSFORM_TYPES /* Counts transforms, not a transform itself. */
};
#define BROTLI_TRANSFORMS_MAX_CUT_OFF BROTLI_TRANSFORM_OMIT_LAST_9
typedef struct BrotliTransforms {
uint16_t prefix_suffix_size;
/* Last character must be null, so prefix_suffix_size must be at least 1. */
const uint8_t* prefix_suffix;
const uint16_t* prefix_suffix_map;
uint32_t num_transforms;
/* Each entry is a [prefix_id, transform, suffix_id] triplet. */
const uint8_t* transforms;
/* Shift for BROTLI_TRANSFORM_SHIFT_FIRST and BROTLI_TRANSFORM_SHIFT_ALL,
must be NULL if and only if no such transforms are present. */
const uint8_t* params;
/* Indices of transforms like ["", BROTLI_TRANSFORM_OMIT_LAST_#, ""].
0-th element corresponds to ["", BROTLI_TRANSFORM_IDENTITY, ""].
-1, if cut-off transform does not exist. */
int16_t cutOffTransforms[BROTLI_TRANSFORMS_MAX_CUT_OFF + 1];
} BrotliTransforms;
/* T is BrotliTransforms*; result is uint8_t. */
#define BROTLI_TRANSFORM_PREFIX_ID(T, I) ((T)->transforms[((I) * 3) + 0])
#define BROTLI_TRANSFORM_TYPE(T, I) ((T)->transforms[((I) * 3) + 1])
#define BROTLI_TRANSFORM_SUFFIX_ID(T, I) ((T)->transforms[((I) * 3) + 2])
/* T is BrotliTransforms*; result is const uint8_t*. */
#define BROTLI_TRANSFORM_PREFIX(T, I) (&(T)->prefix_suffix[ \
(T)->prefix_suffix_map[BROTLI_TRANSFORM_PREFIX_ID(T, I)]])
#define BROTLI_TRANSFORM_SUFFIX(T, I) (&(T)->prefix_suffix[ \
(T)->prefix_suffix_map[BROTLI_TRANSFORM_SUFFIX_ID(T, I)]])
BROTLI_COMMON_API const BrotliTransforms* BrotliGetTransforms(void);
BROTLI_COMMON_API int BrotliTransformDictionaryWord(
uint8_t* dst, const uint8_t* word, int len,
const BrotliTransforms* transforms, int transform_idx);
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_COMMON_TRANSFORM_H_ */

View File

@ -1,26 +0,0 @@
/* Copyright 2016 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Version definition. */
#ifndef BROTLI_COMMON_VERSION_H_
#define BROTLI_COMMON_VERSION_H_
/* This macro should only be used when library is compiled together with client.
If library is dynamically linked, use BrotliDecoderVersion and
BrotliEncoderVersion methods. */
/* Semantic version, calculated as (MAJOR << 24) | (MINOR << 12) | PATCH */
#define BROTLI_VERSION 0x1000009
/* This macro is used by build system to produce Libtool-friendly soname. See
https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
*/
/* ABI version, calculated as (CURRENT << 24) | (REVISION << 12) | AGE */
#define BROTLI_ABI_VERSION 0x1009000
#endif /* BROTLI_COMMON_VERSION_H_ */

View File

@ -1,77 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Bit reading helpers */
#include "bit_reader.h"
#include <brotli/types.h>
#include "../common/platform.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
const uint32_t kBrotliBitMask[33] = { 0x00000000,
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
};
void BrotliInitBitReader(BrotliBitReader* const br) {
br->val_ = 0;
br->bit_pos_ = sizeof(br->val_) << 3;
}
BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
size_t aligned_read_mask = (sizeof(br->val_) >> 1) - 1;
/* Fixing alignment after unaligned BrotliFillWindow would result accumulator
overflow. If unalignment is caused by BrotliSafeReadBits, then there is
enough space in accumulator to fix alignment. */
if (BROTLI_UNALIGNED_READ_FAST) {
aligned_read_mask = 0;
}
if (BrotliGetAvailableBits(br) == 0) {
if (!BrotliPullByte(br)) {
return BROTLI_FALSE;
}
}
while ((((size_t)br->next_in) & aligned_read_mask) != 0) {
if (!BrotliPullByte(br)) {
/* If we consumed all the input, we don't care about the alignment. */
return BROTLI_TRUE;
}
}
return BROTLI_TRUE;
}
BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br,
uint32_t n_bits, uint32_t* val) {
uint32_t low_val;
uint32_t high_val;
BrotliBitReaderState memento;
BROTLI_DCHECK(n_bits <= 32);
BROTLI_DCHECK(n_bits > 24);
BrotliBitReaderSaveState(br, &memento);
if (!BrotliSafeReadBits(br, 16, &low_val) ||
!BrotliSafeReadBits(br, n_bits - 16, &high_val)) {
BrotliBitReaderRestoreState(br, &memento);
return BROTLI_FALSE;
}
*val = low_val | (high_val << 16);
return BROTLI_TRUE;
}
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif

View File

@ -1,370 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Bit reading helpers */
#ifndef BROTLI_DEC_BIT_READER_H_
#define BROTLI_DEC_BIT_READER_H_
#include <string.h> /* memcpy */
#include <brotli/types.h>
#include "../common/constants.h"
#include "../common/platform.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1)
BROTLI_INTERNAL extern const uint32_t kBrotliBitMask[33];
static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) {
/* Masking with this expression turns to a single
"Unsigned Bit Field Extract" UBFX instruction on ARM. */
return ~((0xFFFFFFFFu) << n);
} else {
return kBrotliBitMask[n];
}
}
typedef struct {
brotli_reg_t val_; /* pre-fetched bits */
uint32_t bit_pos_; /* current bit-reading position in val_ */
const uint8_t* next_in; /* the byte we're reading from */
size_t avail_in;
} BrotliBitReader;
typedef struct {
brotli_reg_t val_;
uint32_t bit_pos_;
const uint8_t* next_in;
size_t avail_in;
} BrotliBitReaderState;
/* Initializes the BrotliBitReader fields. */
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br);
/* Ensures that accumulator is not empty.
May consume up to sizeof(brotli_reg_t) - 1 bytes of input.
Returns BROTLI_FALSE if data is required but there is no input available.
For !BROTLI_UNALIGNED_READ_FAST this function also prepares bit reader for
aligned reading. */
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);
/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden
the main code-path. Never called for RFC brotli streams, required only for
"large-window" mode and other extensions. */
BROTLI_INTERNAL BROTLI_NOINLINE BROTLI_BOOL BrotliSafeReadBits32Slow(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val);
static BROTLI_INLINE void BrotliBitReaderSaveState(
BrotliBitReader* const from, BrotliBitReaderState* to) {
to->val_ = from->val_;
to->bit_pos_ = from->bit_pos_;
to->next_in = from->next_in;
to->avail_in = from->avail_in;
}
static BROTLI_INLINE void BrotliBitReaderRestoreState(
BrotliBitReader* const to, BrotliBitReaderState* from) {
to->val_ = from->val_;
to->bit_pos_ = from->bit_pos_;
to->next_in = from->next_in;
to->avail_in = from->avail_in;
}
static BROTLI_INLINE uint32_t BrotliGetAvailableBits(
const BrotliBitReader* br) {
return (BROTLI_64_BITS ? 64 : 32) - br->bit_pos_;
}
/* Returns amount of unread bytes the bit reader still has buffered from the
BrotliInput, including whole bytes in br->val_. Result is capped with
maximal ring-buffer size (larger number won't be utilized anyway). */
static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) {
static const size_t kCap = (size_t)1 << BROTLI_LARGE_MAX_WBITS;
if (br->avail_in > kCap) return kCap;
return br->avail_in + (BrotliGetAvailableBits(br) >> 3);
}
/* Checks if there is at least |num| bytes left in the input ring-buffer
(excluding the bits remaining in br->val_). */
static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
BrotliBitReader* const br, size_t num) {
return TO_BROTLI_BOOL(br->avail_in >= num);
}
/* Guarantees that there are at least |n_bits| + 1 bits in accumulator.
Precondition: accumulator contains at least 1 bit.
|n_bits| should be in the range [1..24] for regular build. For portable
non-64-bit little-endian build only 16 bits are safe to request. */
static BROTLI_INLINE void BrotliFillBitWindow(
BrotliBitReader* const br, uint32_t n_bits) {
#if (BROTLI_64_BITS)
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
(n_bits <= 8)) {
uint32_t bit_pos = br->bit_pos_;
if (bit_pos >= 56) {
br->val_ =
(br->val_ >> 56) | (BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 8);
br->bit_pos_ =
bit_pos ^ 56; /* here same as -= 56 because of the if condition */
br->avail_in -= 7;
br->next_in += 7;
}
} else if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
(n_bits <= 16)) {
uint32_t bit_pos = br->bit_pos_;
if (bit_pos >= 48) {
br->val_ =
(br->val_ >> 48) | (BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 16);
br->bit_pos_ =
bit_pos ^ 48; /* here same as -= 48 because of the if condition */
br->avail_in -= 6;
br->next_in += 6;
}
} else {
uint32_t bit_pos = br->bit_pos_;
if (bit_pos >= 32) {
br->val_ = (br->val_ >> 32) |
(((uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in)) << 32);
br->bit_pos_ =
bit_pos ^ 32; /* here same as -= 32 because of the if condition */
br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
}
}
#else
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
(n_bits <= 8)) {
uint32_t bit_pos = br->bit_pos_;
if (bit_pos >= 24) {
br->val_ =
(br->val_ >> 24) | (BROTLI_UNALIGNED_LOAD32LE(br->next_in) << 8);
br->bit_pos_ =
bit_pos ^ 24; /* here same as -= 24 because of the if condition */
br->avail_in -= 3;
br->next_in += 3;
}
} else {
uint32_t bit_pos = br->bit_pos_;
if (bit_pos >= 16) {
br->val_ = (br->val_ >> 16) |
(((uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in)) << 16);
br->bit_pos_ =
bit_pos ^ 16; /* here same as -= 16 because of the if condition */
br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
}
}
#endif
}
/* Mostly like BrotliFillBitWindow, but guarantees only 16 bits and reads no
more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */
static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) {
BrotliFillBitWindow(br, 17);
}
/* Tries to pull one byte of input to accumulator.
Returns BROTLI_FALSE if there is no input available. */
static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
if (br->avail_in == 0) {
return BROTLI_FALSE;
}
br->val_ >>= 8;
#if (BROTLI_64_BITS)
br->val_ |= ((uint64_t)*br->next_in) << 56;
#else
br->val_ |= ((uint32_t)*br->next_in) << 24;
#endif
br->bit_pos_ -= 8;
--br->avail_in;
++br->next_in;
return BROTLI_TRUE;
}
/* Returns currently available bits.
The number of valid bits could be calculated by BrotliGetAvailableBits. */
static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked(
BrotliBitReader* const br) {
return br->val_ >> br->bit_pos_;
}
/* Like BrotliGetBits, but does not mask the result.
The result contains at least 16 valid bits. */
static BROTLI_INLINE uint32_t BrotliGet16BitsUnmasked(
BrotliBitReader* const br) {
BrotliFillBitWindow(br, 16);
return (uint32_t)BrotliGetBitsUnmasked(br);
}
/* Returns the specified number of bits from |br| without advancing bit
position. */
static BROTLI_INLINE uint32_t BrotliGetBits(
BrotliBitReader* const br, uint32_t n_bits) {
BrotliFillBitWindow(br, n_bits);
return (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
}
/* Tries to peek the specified amount of bits. Returns BROTLI_FALSE, if there
is not enough input. */
static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
while (BrotliGetAvailableBits(br) < n_bits) {
if (!BrotliPullByte(br)) {
return BROTLI_FALSE;
}
}
*val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
return BROTLI_TRUE;
}
/* Advances the bit pos by |n_bits|. */
static BROTLI_INLINE void BrotliDropBits(
BrotliBitReader* const br, uint32_t n_bits) {
br->bit_pos_ += n_bits;
}
static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
uint32_t unused_bytes = BrotliGetAvailableBits(br) >> 3;
uint32_t unused_bits = unused_bytes << 3;
br->avail_in += unused_bytes;
br->next_in -= unused_bytes;
if (unused_bits == sizeof(br->val_) << 3) {
br->val_ = 0;
} else {
br->val_ <<= unused_bits;
}
br->bit_pos_ += unused_bits;
}
/* Reads the specified number of bits from |br| and advances the bit pos.
Precondition: accumulator MUST contain at least |n_bits|. */
static BROTLI_INLINE void BrotliTakeBits(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
*val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
BROTLI_LOG(("[BrotliTakeBits] %d %d %d val: %6x\n",
(int)br->avail_in, (int)br->bit_pos_, (int)n_bits, (int)*val));
BrotliDropBits(br, n_bits);
}
/* Reads the specified number of bits from |br| and advances the bit pos.
Assumes that there is enough input to perform BrotliFillBitWindow.
Up to 24 bits are allowed to be requested from this method. */
static BROTLI_INLINE uint32_t BrotliReadBits24(
BrotliBitReader* const br, uint32_t n_bits) {
BROTLI_DCHECK(n_bits <= 24);
if (BROTLI_64_BITS || (n_bits <= 16)) {
uint32_t val;
BrotliFillBitWindow(br, n_bits);
BrotliTakeBits(br, n_bits, &val);
return val;
} else {
uint32_t low_val;
uint32_t high_val;
BrotliFillBitWindow(br, 16);
BrotliTakeBits(br, 16, &low_val);
BrotliFillBitWindow(br, 8);
BrotliTakeBits(br, n_bits - 16, &high_val);
return low_val | (high_val << 16);
}
}
/* Same as BrotliReadBits24, but allows reading up to 32 bits. */
static BROTLI_INLINE uint32_t BrotliReadBits32(
BrotliBitReader* const br, uint32_t n_bits) {
BROTLI_DCHECK(n_bits <= 32);
if (BROTLI_64_BITS || (n_bits <= 16)) {
uint32_t val;
BrotliFillBitWindow(br, n_bits);
BrotliTakeBits(br, n_bits, &val);
return val;
} else {
uint32_t low_val;
uint32_t high_val;
BrotliFillBitWindow(br, 16);
BrotliTakeBits(br, 16, &low_val);
BrotliFillBitWindow(br, 16);
BrotliTakeBits(br, n_bits - 16, &high_val);
return low_val | (high_val << 16);
}
}
/* Tries to read the specified amount of bits. Returns BROTLI_FALSE, if there
is not enough input. |n_bits| MUST be positive.
Up to 24 bits are allowed to be requested from this method. */
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
BROTLI_DCHECK(n_bits <= 24);
while (BrotliGetAvailableBits(br) < n_bits) {
if (!BrotliPullByte(br)) {
return BROTLI_FALSE;
}
}
BrotliTakeBits(br, n_bits, val);
return BROTLI_TRUE;
}
/* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
BROTLI_DCHECK(n_bits <= 32);
if (BROTLI_64_BITS || (n_bits <= 24)) {
while (BrotliGetAvailableBits(br) < n_bits) {
if (!BrotliPullByte(br)) {
return BROTLI_FALSE;
}
}
BrotliTakeBits(br, n_bits, val);
return BROTLI_TRUE;
} else {
return BrotliSafeReadBits32Slow(br, n_bits, val);
}
}
/* Advances the bit reader position to the next byte boundary and verifies
that any skipped bits are set to zero. */
static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
uint32_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
uint32_t pad_bits = 0;
if (pad_bits_count != 0) {
BrotliTakeBits(br, pad_bits_count, &pad_bits);
}
return TO_BROTLI_BOOL(pad_bits == 0);
}
static BROTLI_INLINE void BrotliDropBytes(BrotliBitReader* br, size_t num) {
br->avail_in -= num;
br->next_in += num;
}
/* Copies remaining input bytes stored in the bit reader to the output. Value
|num| may not be larger than BrotliGetRemainingBytes. The bit reader must be
warmed up again after this. */
static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
BrotliBitReader* br, size_t num) {
while (BrotliGetAvailableBits(br) >= 8 && num > 0) {
*dest = (uint8_t)BrotliGetBitsUnmasked(br);
BrotliDropBits(br, 8);
++dest;
--num;
}
if (num > 0) {
memcpy(dest, br->next_in, num);
BrotliDropBytes(br, num);
}
}
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_DEC_BIT_READER_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,342 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Utilities for building Huffman decoding tables. */
#include "huffman.h"
#include <string.h> /* memcpy, memset */
#include <brotli/types.h>
#include "../common/constants.h"
#include "../common/platform.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#define BROTLI_REVERSE_BITS_MAX 8
#if defined(BROTLI_RBIT)
#define BROTLI_REVERSE_BITS_BASE \
((sizeof(brotli_reg_t) << 3) - BROTLI_REVERSE_BITS_MAX)
#else
#define BROTLI_REVERSE_BITS_BASE 0
static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
#endif /* BROTLI_RBIT */
#define BROTLI_REVERSE_BITS_LOWEST \
((brotli_reg_t)1 << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE))
/* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX),
where reverse(value, len) is the bit-wise reversal of the len least
significant bits of value. */
static BROTLI_INLINE brotli_reg_t BrotliReverseBits(brotli_reg_t num) {
#if defined(BROTLI_RBIT)
return BROTLI_RBIT(num);
#else
return kReverseBits[num];
#endif
}
/* Stores code in table[0], table[step], table[2*step], ..., table[end] */
/* Assumes that end is an integer multiple of step */
static BROTLI_INLINE void ReplicateValue(HuffmanCode* table,
int step, int end,
HuffmanCode code) {
do {
end -= step;
table[end] = code;
} while (end > 0);
}
/* Returns the table width of the next 2nd level table. |count| is the histogram
of bit lengths for the remaining symbols, |len| is the code length of the
next processed symbol. */
static BROTLI_INLINE int NextTableBitSize(const uint16_t* const count,
int len, int root_bits) {
int left = 1 << (len - root_bits);
while (len < BROTLI_HUFFMAN_MAX_CODE_LENGTH) {
left -= count[len];
if (left <= 0) break;
++len;
left <<= 1;
}
return len - root_bits;
}
void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
const uint8_t* const code_lengths,
uint16_t* count) {
HuffmanCode code; /* current table entry */
int symbol; /* symbol index in original or sorted table */
brotli_reg_t key; /* prefix code */
brotli_reg_t key_step; /* prefix code addend */
int step; /* step size to replicate values in current table */
int table_size; /* size of current table */
int sorted[BROTLI_CODE_LENGTH_CODES]; /* symbols sorted by code length */
/* offsets in sorted table for each length */
int offset[BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1];
int bits;
int bits_count;
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <=
BROTLI_REVERSE_BITS_MAX);
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5);
/* Generate offsets into sorted symbol table by code length. */
symbol = -1;
bits = 1;
/* BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5 */
BROTLI_REPEAT_5({
symbol += count[bits];
offset[bits] = symbol;
bits++;
});
/* Symbols with code length 0 are placed after all other symbols. */
offset[0] = BROTLI_CODE_LENGTH_CODES - 1;
/* Sort symbols by length, by symbol order within each length. */
symbol = BROTLI_CODE_LENGTH_CODES;
do {
BROTLI_REPEAT_6({
symbol--;
sorted[offset[code_lengths[symbol]]--] = symbol;
});
} while (symbol != 0);
table_size = 1 << BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH;
/* Special case: all symbols but one have 0 code length. */
if (offset[0] == 0) {
code = ConstructHuffmanCode(0, (uint16_t)sorted[0]);
for (key = 0; key < (brotli_reg_t)table_size; ++key) {
table[key] = code;
}
return;
}
/* Fill in table. */
key = 0;
key_step = BROTLI_REVERSE_BITS_LOWEST;
symbol = 0;
bits = 1;
step = 2;
do {
for (bits_count = count[bits]; bits_count != 0; --bits_count) {
code = ConstructHuffmanCode((uint8_t)bits, (uint16_t)sorted[symbol++]);
ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code);
key += key_step;
}
step <<= 1;
key_step >>= 1;
} while (++bits <= BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
}
uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
int root_bits,
const uint16_t* const symbol_lists,
uint16_t* count) {
HuffmanCode code; /* current table entry */
HuffmanCode* table; /* next available space in table */
int len; /* current code length */
int symbol; /* symbol index in original or sorted table */
brotli_reg_t key; /* prefix code */
brotli_reg_t key_step; /* prefix code addend */
brotli_reg_t sub_key; /* 2nd level table prefix code */
brotli_reg_t sub_key_step; /* 2nd level table prefix code addend */
int step; /* step size to replicate values in current table */
int table_bits; /* key length of current table */
int table_size; /* size of current table */
int total_size; /* sum of root table size and 2nd level table sizes */
int max_length = -1;
int bits;
int bits_count;
BROTLI_DCHECK(root_bits <= BROTLI_REVERSE_BITS_MAX);
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH - root_bits <=
BROTLI_REVERSE_BITS_MAX);
while (symbol_lists[max_length] == 0xFFFF) max_length--;
max_length += BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1;
table = root_table;
table_bits = root_bits;
table_size = 1 << table_bits;
total_size = table_size;
/* Fill in the root table. Reduce the table size to if possible,
and create the repetitions by memcpy. */
if (table_bits > max_length) {
table_bits = max_length;
table_size = 1 << table_bits;
}
key = 0;
key_step = BROTLI_REVERSE_BITS_LOWEST;
bits = 1;
step = 2;
do {
symbol = bits - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
for (bits_count = count[bits]; bits_count != 0; --bits_count) {
symbol = symbol_lists[symbol];
code = ConstructHuffmanCode((uint8_t)bits, (uint16_t)symbol);
ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code);
key += key_step;
}
step <<= 1;
key_step >>= 1;
} while (++bits <= table_bits);
/* If root_bits != table_bits then replicate to fill the remaining slots. */
while (total_size != table_size) {
memcpy(&table[table_size], &table[0],
(size_t)table_size * sizeof(table[0]));
table_size <<= 1;
}
/* Fill in 2nd level tables and add pointers to root table. */
key_step = BROTLI_REVERSE_BITS_LOWEST >> (root_bits - 1);
sub_key = (BROTLI_REVERSE_BITS_LOWEST << 1);
sub_key_step = BROTLI_REVERSE_BITS_LOWEST;
for (len = root_bits + 1, step = 2; len <= max_length; ++len) {
symbol = len - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
for (; count[len] != 0; --count[len]) {
if (sub_key == (BROTLI_REVERSE_BITS_LOWEST << 1U)) {
table += table_size;
table_bits = NextTableBitSize(count, len, root_bits);
table_size = 1 << table_bits;
total_size += table_size;
sub_key = BrotliReverseBits(key);
key += key_step;
root_table[sub_key] = ConstructHuffmanCode(
(uint8_t)(table_bits + root_bits),
(uint16_t)(((size_t)(table - root_table)) - sub_key));
sub_key = 0;
}
symbol = symbol_lists[symbol];
code = ConstructHuffmanCode((uint8_t)(len - root_bits), (uint16_t)symbol);
ReplicateValue(
&table[BrotliReverseBits(sub_key)], step, table_size, code);
sub_key += sub_key_step;
}
step <<= 1;
sub_key_step >>= 1;
}
return (uint32_t)total_size;
}
uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
int root_bits,
uint16_t* val,
uint32_t num_symbols) {
uint32_t table_size = 1;
const uint32_t goal_size = 1U << root_bits;
switch (num_symbols) {
case 0:
table[0] = ConstructHuffmanCode(0, val[0]);
break;
case 1:
if (val[1] > val[0]) {
table[0] = ConstructHuffmanCode(1, val[0]);
table[1] = ConstructHuffmanCode(1, val[1]);
} else {
table[0] = ConstructHuffmanCode(1, val[1]);
table[1] = ConstructHuffmanCode(1, val[0]);
}
table_size = 2;
break;
case 2:
table[0] = ConstructHuffmanCode(1, val[0]);
table[2] = ConstructHuffmanCode(1, val[0]);
if (val[2] > val[1]) {
table[1] = ConstructHuffmanCode(2, val[1]);
table[3] = ConstructHuffmanCode(2, val[2]);
} else {
table[1] = ConstructHuffmanCode(2, val[2]);
table[3] = ConstructHuffmanCode(2, val[1]);
}
table_size = 4;
break;
case 3: {
int i, k;
for (i = 0; i < 3; ++i) {
for (k = i + 1; k < 4; ++k) {
if (val[k] < val[i]) {
uint16_t t = val[k];
val[k] = val[i];
val[i] = t;
}
}
}
table[0] = ConstructHuffmanCode(2, val[0]);
table[2] = ConstructHuffmanCode(2, val[1]);
table[1] = ConstructHuffmanCode(2, val[2]);
table[3] = ConstructHuffmanCode(2, val[3]);
table_size = 4;
break;
}
case 4: {
if (val[3] < val[2]) {
uint16_t t = val[3];
val[3] = val[2];
val[2] = t;
}
table[0] = ConstructHuffmanCode(1, val[0]);
table[1] = ConstructHuffmanCode(2, val[1]);
table[2] = ConstructHuffmanCode(1, val[0]);
table[3] = ConstructHuffmanCode(3, val[2]);
table[4] = ConstructHuffmanCode(1, val[0]);
table[5] = ConstructHuffmanCode(2, val[1]);
table[6] = ConstructHuffmanCode(1, val[0]);
table[7] = ConstructHuffmanCode(3, val[3]);
table_size = 8;
break;
}
}
while (table_size != goal_size) {
memcpy(&table[table_size], &table[0],
(size_t)table_size * sizeof(table[0]));
table_size <<= 1;
}
return goal_size;
}
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif

View File

@ -1,122 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Utilities for building Huffman decoding tables. */
#ifndef BROTLI_DEC_HUFFMAN_H_
#define BROTLI_DEC_HUFFMAN_H_
#include <brotli/types.h>
#include "../common/platform.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15
/* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */
#define BROTLI_HUFFMAN_MAX_SIZE_26 396
/* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */
#define BROTLI_HUFFMAN_MAX_SIZE_258 632
/* BROTLI_MAX_CONTEXT_MAP_SYMBOLS == 272 */
#define BROTLI_HUFFMAN_MAX_SIZE_272 646
#define BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH 5
#if ((defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_32)) && \
BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0))
#define BROTLI_HUFFMAN_CODE_FAST_LOAD
#endif
#if !defined(BROTLI_HUFFMAN_CODE_FAST_LOAD)
/* Do not create this struct directly - use the ConstructHuffmanCode
* constructor below! */
typedef struct {
uint8_t bits; /* number of bits used for this symbol */
uint16_t value; /* symbol value or table offset */
} HuffmanCode;
static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
const uint16_t value) {
HuffmanCode h;
h.bits = bits;
h.value = value;
return h;
}
/* Please use the following macros to optimize HuffmanCode accesses in hot
* paths.
*
* For example, assuming |table| contains a HuffmanCode pointer:
*
* BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
* BROTLI_HC_ADJUST_TABLE_INDEX(table, index_into_table);
* *bits = BROTLI_HC_GET_BITS(table);
* *value = BROTLI_HC_GET_VALUE(table);
* BROTLI_HC_ADJUST_TABLE_INDEX(table, offset);
* *bits2 = BROTLI_HC_GET_BITS(table);
* *value2 = BROTLI_HC_GET_VALUE(table);
*
*/
#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H)
#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V)
/* These must be given a HuffmanCode pointer! */
#define BROTLI_HC_FAST_LOAD_BITS(H) (H->bits)
#define BROTLI_HC_FAST_LOAD_VALUE(H) (H->value)
#else /* BROTLI_HUFFMAN_CODE_FAST_LOAD */
typedef BROTLI_ALIGNED(4) uint32_t HuffmanCode;
static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
const uint16_t value) {
return (HuffmanCode) ((value & 0xFFFF) << 16) | (bits & 0xFF);
}
#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H) uint32_t __fastload_##H = (*H)
#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V); __fastload_##H = (*H)
/* These must be given a HuffmanCode pointer! */
#define BROTLI_HC_FAST_LOAD_BITS(H) ((__fastload_##H) & 0xFF)
#define BROTLI_HC_FAST_LOAD_VALUE(H) ((__fastload_##H) >> 16)
#endif /* BROTLI_HUFFMAN_CODE_FAST_LOAD */
/* Builds Huffman lookup table assuming code lengths are in symbol order. */
BROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
const uint8_t* const code_lengths, uint16_t* count);
/* Builds Huffman lookup table assuming code lengths are in symbol order.
Returns size of resulting table. */
BROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
int root_bits, const uint16_t* const symbol_lists, uint16_t* count);
/* Builds a simple Huffman table. The |num_symbols| parameter is to be
interpreted as follows: 0 means 1 symbol, 1 means 2 symbols,
2 means 3 symbols, 3 means 4 symbols with lengths [2, 2, 2, 2],
4 means 4 symbols with lengths [1, 2, 3, 3]. */
BROTLI_INTERNAL uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
int root_bits, uint16_t* symbols, uint32_t num_symbols);
/* Contains a collection of Huffman trees with the same alphabet size. */
/* alphabet_size_limit is needed due to simple codes, since
log2(alphabet_size_max) could be greater than log2(alphabet_size_limit). */
typedef struct {
HuffmanCode** htrees;
HuffmanCode* codes;
uint16_t alphabet_size_max;
uint16_t alphabet_size_limit;
uint16_t num_htrees;
} HuffmanTreeGroup;
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_DEC_HUFFMAN_H_ */

View File

@ -1,733 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Lookup tables to map prefix codes to value ranges. This is used during
decoding of the block lengths, literal insertion lengths and copy lengths. */
#ifndef BROTLI_DEC_PREFIX_H_
#define BROTLI_DEC_PREFIX_H_
#include <brotli/types.h>
#include "../common/constants.h"
typedef struct CmdLutElement {
uint8_t insert_len_extra_bits;
uint8_t copy_len_extra_bits;
int8_t distance_code;
uint8_t context;
uint16_t insert_len_offset;
uint16_t copy_len_offset;
} CmdLutElement;
static const CmdLutElement kCmdLut[BROTLI_NUM_COMMAND_SYMBOLS] = {
{ 0x00, 0x00, 0, 0x00, 0x0000, 0x0002 },
{ 0x00, 0x00, 0, 0x01, 0x0000, 0x0003 },
{ 0x00, 0x00, 0, 0x02, 0x0000, 0x0004 },
{ 0x00, 0x00, 0, 0x03, 0x0000, 0x0005 },
{ 0x00, 0x00, 0, 0x03, 0x0000, 0x0006 },
{ 0x00, 0x00, 0, 0x03, 0x0000, 0x0007 },
{ 0x00, 0x00, 0, 0x03, 0x0000, 0x0008 },
{ 0x00, 0x00, 0, 0x03, 0x0000, 0x0009 },
{ 0x00, 0x00, 0, 0x00, 0x0001, 0x0002 },
{ 0x00, 0x00, 0, 0x01, 0x0001, 0x0003 },
{ 0x00, 0x00, 0, 0x02, 0x0001, 0x0004 },
{ 0x00, 0x00, 0, 0x03, 0x0001, 0x0005 },
{ 0x00, 0x00, 0, 0x03, 0x0001, 0x0006 },
{ 0x00, 0x00, 0, 0x03, 0x0001, 0x0007 },
{ 0x00, 0x00, 0, 0x03, 0x0001, 0x0008 },
{ 0x00, 0x00, 0, 0x03, 0x0001, 0x0009 },
{ 0x00, 0x00, 0, 0x00, 0x0002, 0x0002 },
{ 0x00, 0x00, 0, 0x01, 0x0002, 0x0003 },
{ 0x00, 0x00, 0, 0x02, 0x0002, 0x0004 },
{ 0x00, 0x00, 0, 0x03, 0x0002, 0x0005 },
{ 0x00, 0x00, 0, 0x03, 0x0002, 0x0006 },
{ 0x00, 0x00, 0, 0x03, 0x0002, 0x0007 },
{ 0x00, 0x00, 0, 0x03, 0x0002, 0x0008 },
{ 0x00, 0x00, 0, 0x03, 0x0002, 0x0009 },
{ 0x00, 0x00, 0, 0x00, 0x0003, 0x0002 },
{ 0x00, 0x00, 0, 0x01, 0x0003, 0x0003 },
{ 0x00, 0x00, 0, 0x02, 0x0003, 0x0004 },
{ 0x00, 0x00, 0, 0x03, 0x0003, 0x0005 },
{ 0x00, 0x00, 0, 0x03, 0x0003, 0x0006 },
{ 0x00, 0x00, 0, 0x03, 0x0003, 0x0007 },
{ 0x00, 0x00, 0, 0x03, 0x0003, 0x0008 },
{ 0x00, 0x00, 0, 0x03, 0x0003, 0x0009 },
{ 0x00, 0x00, 0, 0x00, 0x0004, 0x0002 },
{ 0x00, 0x00, 0, 0x01, 0x0004, 0x0003 },
{ 0x00, 0x00, 0, 0x02, 0x0004, 0x0004 },
{ 0x00, 0x00, 0, 0x03, 0x0004, 0x0005 },
{ 0x00, 0x00, 0, 0x03, 0x0004, 0x0006 },
{ 0x00, 0x00, 0, 0x03, 0x0004, 0x0007 },
{ 0x00, 0x00, 0, 0x03, 0x0004, 0x0008 },
{ 0x00, 0x00, 0, 0x03, 0x0004, 0x0009 },
{ 0x00, 0x00, 0, 0x00, 0x0005, 0x0002 },
{ 0x00, 0x00, 0, 0x01, 0x0005, 0x0003 },
{ 0x00, 0x00, 0, 0x02, 0x0005, 0x0004 },
{ 0x00, 0x00, 0, 0x03, 0x0005, 0x0005 },
{ 0x00, 0x00, 0, 0x03, 0x0005, 0x0006 },
{ 0x00, 0x00, 0, 0x03, 0x0005, 0x0007 },
{ 0x00, 0x00, 0, 0x03, 0x0005, 0x0008 },
{ 0x00, 0x00, 0, 0x03, 0x0005, 0x0009 },
{ 0x01, 0x00, 0, 0x00, 0x0006, 0x0002 },
{ 0x01, 0x00, 0, 0x01, 0x0006, 0x0003 },
{ 0x01, 0x00, 0, 0x02, 0x0006, 0x0004 },
{ 0x01, 0x00, 0, 0x03, 0x0006, 0x0005 },
{ 0x01, 0x00, 0, 0x03, 0x0006, 0x0006 },
{ 0x01, 0x00, 0, 0x03, 0x0006, 0x0007 },
{ 0x01, 0x00, 0, 0x03, 0x0006, 0x0008 },
{ 0x01, 0x00, 0, 0x03, 0x0006, 0x0009 },
{ 0x01, 0x00, 0, 0x00, 0x0008, 0x0002 },
{ 0x01, 0x00, 0, 0x01, 0x0008, 0x0003 },
{ 0x01, 0x00, 0, 0x02, 0x0008, 0x0004 },
{ 0x01, 0x00, 0, 0x03, 0x0008, 0x0005 },
{ 0x01, 0x00, 0, 0x03, 0x0008, 0x0006 },
{ 0x01, 0x00, 0, 0x03, 0x0008, 0x0007 },
{ 0x01, 0x00, 0, 0x03, 0x0008, 0x0008 },
{ 0x01, 0x00, 0, 0x03, 0x0008, 0x0009 },
{ 0x00, 0x01, 0, 0x03, 0x0000, 0x000a },
{ 0x00, 0x01, 0, 0x03, 0x0000, 0x000c },
{ 0x00, 0x02, 0, 0x03, 0x0000, 0x000e },
{ 0x00, 0x02, 0, 0x03, 0x0000, 0x0012 },
{ 0x00, 0x03, 0, 0x03, 0x0000, 0x0016 },
{ 0x00, 0x03, 0, 0x03, 0x0000, 0x001e },
{ 0x00, 0x04, 0, 0x03, 0x0000, 0x0026 },
{ 0x00, 0x04, 0, 0x03, 0x0000, 0x0036 },
{ 0x00, 0x01, 0, 0x03, 0x0001, 0x000a },
{ 0x00, 0x01, 0, 0x03, 0x0001, 0x000c },
{ 0x00, 0x02, 0, 0x03, 0x0001, 0x000e },
{ 0x00, 0x02, 0, 0x03, 0x0001, 0x0012 },
{ 0x00, 0x03, 0, 0x03, 0x0001, 0x0016 },
{ 0x00, 0x03, 0, 0x03, 0x0001, 0x001e },
{ 0x00, 0x04, 0, 0x03, 0x0001, 0x0026 },
{ 0x00, 0x04, 0, 0x03, 0x0001, 0x0036 },
{ 0x00, 0x01, 0, 0x03, 0x0002, 0x000a },
{ 0x00, 0x01, 0, 0x03, 0x0002, 0x000c },
{ 0x00, 0x02, 0, 0x03, 0x0002, 0x000e },
{ 0x00, 0x02, 0, 0x03, 0x0002, 0x0012 },
{ 0x00, 0x03, 0, 0x03, 0x0002, 0x0016 },
{ 0x00, 0x03, 0, 0x03, 0x0002, 0x001e },
{ 0x00, 0x04, 0, 0x03, 0x0002, 0x0026 },
{ 0x00, 0x04, 0, 0x03, 0x0002, 0x0036 },
{ 0x00, 0x01, 0, 0x03, 0x0003, 0x000a },
{ 0x00, 0x01, 0, 0x03, 0x0003, 0x000c },
{ 0x00, 0x02, 0, 0x03, 0x0003, 0x000e },
{ 0x00, 0x02, 0, 0x03, 0x0003, 0x0012 },
{ 0x00, 0x03, 0, 0x03, 0x0003, 0x0016 },
{ 0x00, 0x03, 0, 0x03, 0x0003, 0x001e },
{ 0x00, 0x04, 0, 0x03, 0x0003, 0x0026 },
{ 0x00, 0x04, 0, 0x03, 0x0003, 0x0036 },
{ 0x00, 0x01, 0, 0x03, 0x0004, 0x000a },
{ 0x00, 0x01, 0, 0x03, 0x0004, 0x000c },
{ 0x00, 0x02, 0, 0x03, 0x0004, 0x000e },
{ 0x00, 0x02, 0, 0x03, 0x0004, 0x0012 },
{ 0x00, 0x03, 0, 0x03, 0x0004, 0x0016 },
{ 0x00, 0x03, 0, 0x03, 0x0004, 0x001e },
{ 0x00, 0x04, 0, 0x03, 0x0004, 0x0026 },
{ 0x00, 0x04, 0, 0x03, 0x0004, 0x0036 },
{ 0x00, 0x01, 0, 0x03, 0x0005, 0x000a },
{ 0x00, 0x01, 0, 0x03, 0x0005, 0x000c },
{ 0x00, 0x02, 0, 0x03, 0x0005, 0x000e },
{ 0x00, 0x02, 0, 0x03, 0x0005, 0x0012 },
{ 0x00, 0x03, 0, 0x03, 0x0005, 0x0016 },
{ 0x00, 0x03, 0, 0x03, 0x0005, 0x001e },
{ 0x00, 0x04, 0, 0x03, 0x0005, 0x0026 },
{ 0x00, 0x04, 0, 0x03, 0x0005, 0x0036 },
{ 0x01, 0x01, 0, 0x03, 0x0006, 0x000a },
{ 0x01, 0x01, 0, 0x03, 0x0006, 0x000c },
{ 0x01, 0x02, 0, 0x03, 0x0006, 0x000e },
{ 0x01, 0x02, 0, 0x03, 0x0006, 0x0012 },
{ 0x01, 0x03, 0, 0x03, 0x0006, 0x0016 },
{ 0x01, 0x03, 0, 0x03, 0x0006, 0x001e },
{ 0x01, 0x04, 0, 0x03, 0x0006, 0x0026 },
{ 0x01, 0x04, 0, 0x03, 0x0006, 0x0036 },
{ 0x01, 0x01, 0, 0x03, 0x0008, 0x000a },
{ 0x01, 0x01, 0, 0x03, 0x0008, 0x000c },
{ 0x01, 0x02, 0, 0x03, 0x0008, 0x000e },
{ 0x01, 0x02, 0, 0x03, 0x0008, 0x0012 },
{ 0x01, 0x03, 0, 0x03, 0x0008, 0x0016 },
{ 0x01, 0x03, 0, 0x03, 0x0008, 0x001e },
{ 0x01, 0x04, 0, 0x03, 0x0008, 0x0026 },
{ 0x01, 0x04, 0, 0x03, 0x0008, 0x0036 },
{ 0x00, 0x00, -1, 0x00, 0x0000, 0x0002 },
{ 0x00, 0x00, -1, 0x01, 0x0000, 0x0003 },
{ 0x00, 0x00, -1, 0x02, 0x0000, 0x0004 },
{ 0x00, 0x00, -1, 0x03, 0x0000, 0x0005 },
{ 0x00, 0x00, -1, 0x03, 0x0000, 0x0006 },
{ 0x00, 0x00, -1, 0x03, 0x0000, 0x0007 },
{ 0x00, 0x00, -1, 0x03, 0x0000, 0x0008 },
{ 0x00, 0x00, -1, 0x03, 0x0000, 0x0009 },
{ 0x00, 0x00, -1, 0x00, 0x0001, 0x0002 },
{ 0x00, 0x00, -1, 0x01, 0x0001, 0x0003 },
{ 0x00, 0x00, -1, 0x02, 0x0001, 0x0004 },
{ 0x00, 0x00, -1, 0x03, 0x0001, 0x0005 },
{ 0x00, 0x00, -1, 0x03, 0x0001, 0x0006 },
{ 0x00, 0x00, -1, 0x03, 0x0001, 0x0007 },
{ 0x00, 0x00, -1, 0x03, 0x0001, 0x0008 },
{ 0x00, 0x00, -1, 0x03, 0x0001, 0x0009 },
{ 0x00, 0x00, -1, 0x00, 0x0002, 0x0002 },
{ 0x00, 0x00, -1, 0x01, 0x0002, 0x0003 },
{ 0x00, 0x00, -1, 0x02, 0x0002, 0x0004 },
{ 0x00, 0x00, -1, 0x03, 0x0002, 0x0005 },
{ 0x00, 0x00, -1, 0x03, 0x0002, 0x0006 },
{ 0x00, 0x00, -1, 0x03, 0x0002, 0x0007 },
{ 0x00, 0x00, -1, 0x03, 0x0002, 0x0008 },
{ 0x00, 0x00, -1, 0x03, 0x0002, 0x0009 },
{ 0x00, 0x00, -1, 0x00, 0x0003, 0x0002 },
{ 0x00, 0x00, -1, 0x01, 0x0003, 0x0003 },
{ 0x00, 0x00, -1, 0x02, 0x0003, 0x0004 },
{ 0x00, 0x00, -1, 0x03, 0x0003, 0x0005 },
{ 0x00, 0x00, -1, 0x03, 0x0003, 0x0006 },
{ 0x00, 0x00, -1, 0x03, 0x0003, 0x0007 },
{ 0x00, 0x00, -1, 0x03, 0x0003, 0x0008 },
{ 0x00, 0x00, -1, 0x03, 0x0003, 0x0009 },
{ 0x00, 0x00, -1, 0x00, 0x0004, 0x0002 },
{ 0x00, 0x00, -1, 0x01, 0x0004, 0x0003 },
{ 0x00, 0x00, -1, 0x02, 0x0004, 0x0004 },
{ 0x00, 0x00, -1, 0x03, 0x0004, 0x0005 },
{ 0x00, 0x00, -1, 0x03, 0x0004, 0x0006 },
{ 0x00, 0x00, -1, 0x03, 0x0004, 0x0007 },
{ 0x00, 0x00, -1, 0x03, 0x0004, 0x0008 },
{ 0x00, 0x00, -1, 0x03, 0x0004, 0x0009 },
{ 0x00, 0x00, -1, 0x00, 0x0005, 0x0002 },
{ 0x00, 0x00, -1, 0x01, 0x0005, 0x0003 },
{ 0x00, 0x00, -1, 0x02, 0x0005, 0x0004 },
{ 0x00, 0x00, -1, 0x03, 0x0005, 0x0005 },
{ 0x00, 0x00, -1, 0x03, 0x0005, 0x0006 },
{ 0x00, 0x00, -1, 0x03, 0x0005, 0x0007 },
{ 0x00, 0x00, -1, 0x03, 0x0005, 0x0008 },
{ 0x00, 0x00, -1, 0x03, 0x0005, 0x0009 },
{ 0x01, 0x00, -1, 0x00, 0x0006, 0x0002 },
{ 0x01, 0x00, -1, 0x01, 0x0006, 0x0003 },
{ 0x01, 0x00, -1, 0x02, 0x0006, 0x0004 },
{ 0x01, 0x00, -1, 0x03, 0x0006, 0x0005 },
{ 0x01, 0x00, -1, 0x03, 0x0006, 0x0006 },
{ 0x01, 0x00, -1, 0x03, 0x0006, 0x0007 },
{ 0x01, 0x00, -1, 0x03, 0x0006, 0x0008 },
{ 0x01, 0x00, -1, 0x03, 0x0006, 0x0009 },
{ 0x01, 0x00, -1, 0x00, 0x0008, 0x0002 },
{ 0x01, 0x00, -1, 0x01, 0x0008, 0x0003 },
{ 0x01, 0x00, -1, 0x02, 0x0008, 0x0004 },
{ 0x01, 0x00, -1, 0x03, 0x0008, 0x0005 },
{ 0x01, 0x00, -1, 0x03, 0x0008, 0x0006 },
{ 0x01, 0x00, -1, 0x03, 0x0008, 0x0007 },
{ 0x01, 0x00, -1, 0x03, 0x0008, 0x0008 },
{ 0x01, 0x00, -1, 0x03, 0x0008, 0x0009 },
{ 0x00, 0x01, -1, 0x03, 0x0000, 0x000a },
{ 0x00, 0x01, -1, 0x03, 0x0000, 0x000c },
{ 0x00, 0x02, -1, 0x03, 0x0000, 0x000e },
{ 0x00, 0x02, -1, 0x03, 0x0000, 0x0012 },
{ 0x00, 0x03, -1, 0x03, 0x0000, 0x0016 },
{ 0x00, 0x03, -1, 0x03, 0x0000, 0x001e },
{ 0x00, 0x04, -1, 0x03, 0x0000, 0x0026 },
{ 0x00, 0x04, -1, 0x03, 0x0000, 0x0036 },
{ 0x00, 0x01, -1, 0x03, 0x0001, 0x000a },
{ 0x00, 0x01, -1, 0x03, 0x0001, 0x000c },
{ 0x00, 0x02, -1, 0x03, 0x0001, 0x000e },
{ 0x00, 0x02, -1, 0x03, 0x0001, 0x0012 },
{ 0x00, 0x03, -1, 0x03, 0x0001, 0x0016 },
{ 0x00, 0x03, -1, 0x03, 0x0001, 0x001e },
{ 0x00, 0x04, -1, 0x03, 0x0001, 0x0026 },
{ 0x00, 0x04, -1, 0x03, 0x0001, 0x0036 },
{ 0x00, 0x01, -1, 0x03, 0x0002, 0x000a },
{ 0x00, 0x01, -1, 0x03, 0x0002, 0x000c },
{ 0x00, 0x02, -1, 0x03, 0x0002, 0x000e },
{ 0x00, 0x02, -1, 0x03, 0x0002, 0x0012 },
{ 0x00, 0x03, -1, 0x03, 0x0002, 0x0016 },
{ 0x00, 0x03, -1, 0x03, 0x0002, 0x001e },
{ 0x00, 0x04, -1, 0x03, 0x0002, 0x0026 },
{ 0x00, 0x04, -1, 0x03, 0x0002, 0x0036 },
{ 0x00, 0x01, -1, 0x03, 0x0003, 0x000a },
{ 0x00, 0x01, -1, 0x03, 0x0003, 0x000c },
{ 0x00, 0x02, -1, 0x03, 0x0003, 0x000e },
{ 0x00, 0x02, -1, 0x03, 0x0003, 0x0012 },
{ 0x00, 0x03, -1, 0x03, 0x0003, 0x0016 },
{ 0x00, 0x03, -1, 0x03, 0x0003, 0x001e },
{ 0x00, 0x04, -1, 0x03, 0x0003, 0x0026 },
{ 0x00, 0x04, -1, 0x03, 0x0003, 0x0036 },
{ 0x00, 0x01, -1, 0x03, 0x0004, 0x000a },
{ 0x00, 0x01, -1, 0x03, 0x0004, 0x000c },
{ 0x00, 0x02, -1, 0x03, 0x0004, 0x000e },
{ 0x00, 0x02, -1, 0x03, 0x0004, 0x0012 },
{ 0x00, 0x03, -1, 0x03, 0x0004, 0x0016 },
{ 0x00, 0x03, -1, 0x03, 0x0004, 0x001e },
{ 0x00, 0x04, -1, 0x03, 0x0004, 0x0026 },
{ 0x00, 0x04, -1, 0x03, 0x0004, 0x0036 },
{ 0x00, 0x01, -1, 0x03, 0x0005, 0x000a },
{ 0x00, 0x01, -1, 0x03, 0x0005, 0x000c },
{ 0x00, 0x02, -1, 0x03, 0x0005, 0x000e },
{ 0x00, 0x02, -1, 0x03, 0x0005, 0x0012 },
{ 0x00, 0x03, -1, 0x03, 0x0005, 0x0016 },
{ 0x00, 0x03, -1, 0x03, 0x0005, 0x001e },
{ 0x00, 0x04, -1, 0x03, 0x0005, 0x0026 },
{ 0x00, 0x04, -1, 0x03, 0x0005, 0x0036 },
{ 0x01, 0x01, -1, 0x03, 0x0006, 0x000a },
{ 0x01, 0x01, -1, 0x03, 0x0006, 0x000c },
{ 0x01, 0x02, -1, 0x03, 0x0006, 0x000e },
{ 0x01, 0x02, -1, 0x03, 0x0006, 0x0012 },
{ 0x01, 0x03, -1, 0x03, 0x0006, 0x0016 },
{ 0x01, 0x03, -1, 0x03, 0x0006, 0x001e },
{ 0x01, 0x04, -1, 0x03, 0x0006, 0x0026 },
{ 0x01, 0x04, -1, 0x03, 0x0006, 0x0036 },
{ 0x01, 0x01, -1, 0x03, 0x0008, 0x000a },
{ 0x01, 0x01, -1, 0x03, 0x0008, 0x000c },
{ 0x01, 0x02, -1, 0x03, 0x0008, 0x000e },
{ 0x01, 0x02, -1, 0x03, 0x0008, 0x0012 },
{ 0x01, 0x03, -1, 0x03, 0x0008, 0x0016 },
{ 0x01, 0x03, -1, 0x03, 0x0008, 0x001e },
{ 0x01, 0x04, -1, 0x03, 0x0008, 0x0026 },
{ 0x01, 0x04, -1, 0x03, 0x0008, 0x0036 },
{ 0x02, 0x00, -1, 0x00, 0x000a, 0x0002 },
{ 0x02, 0x00, -1, 0x01, 0x000a, 0x0003 },
{ 0x02, 0x00, -1, 0x02, 0x000a, 0x0004 },
{ 0x02, 0x00, -1, 0x03, 0x000a, 0x0005 },
{ 0x02, 0x00, -1, 0x03, 0x000a, 0x0006 },
{ 0x02, 0x00, -1, 0x03, 0x000a, 0x0007 },
{ 0x02, 0x00, -1, 0x03, 0x000a, 0x0008 },
{ 0x02, 0x00, -1, 0x03, 0x000a, 0x0009 },
{ 0x02, 0x00, -1, 0x00, 0x000e, 0x0002 },
{ 0x02, 0x00, -1, 0x01, 0x000e, 0x0003 },
{ 0x02, 0x00, -1, 0x02, 0x000e, 0x0004 },
{ 0x02, 0x00, -1, 0x03, 0x000e, 0x0005 },
{ 0x02, 0x00, -1, 0x03, 0x000e, 0x0006 },
{ 0x02, 0x00, -1, 0x03, 0x000e, 0x0007 },
{ 0x02, 0x00, -1, 0x03, 0x000e, 0x0008 },
{ 0x02, 0x00, -1, 0x03, 0x000e, 0x0009 },
{ 0x03, 0x00, -1, 0x00, 0x0012, 0x0002 },
{ 0x03, 0x00, -1, 0x01, 0x0012, 0x0003 },
{ 0x03, 0x00, -1, 0x02, 0x0012, 0x0004 },
{ 0x03, 0x00, -1, 0x03, 0x0012, 0x0005 },
{ 0x03, 0x00, -1, 0x03, 0x0012, 0x0006 },
{ 0x03, 0x00, -1, 0x03, 0x0012, 0x0007 },
{ 0x03, 0x00, -1, 0x03, 0x0012, 0x0008 },
{ 0x03, 0x00, -1, 0x03, 0x0012, 0x0009 },
{ 0x03, 0x00, -1, 0x00, 0x001a, 0x0002 },
{ 0x03, 0x00, -1, 0x01, 0x001a, 0x0003 },
{ 0x03, 0x00, -1, 0x02, 0x001a, 0x0004 },
{ 0x03, 0x00, -1, 0x03, 0x001a, 0x0005 },
{ 0x03, 0x00, -1, 0x03, 0x001a, 0x0006 },
{ 0x03, 0x00, -1, 0x03, 0x001a, 0x0007 },
{ 0x03, 0x00, -1, 0x03, 0x001a, 0x0008 },
{ 0x03, 0x00, -1, 0x03, 0x001a, 0x0009 },
{ 0x04, 0x00, -1, 0x00, 0x0022, 0x0002 },
{ 0x04, 0x00, -1, 0x01, 0x0022, 0x0003 },
{ 0x04, 0x00, -1, 0x02, 0x0022, 0x0004 },
{ 0x04, 0x00, -1, 0x03, 0x0022, 0x0005 },
{ 0x04, 0x00, -1, 0x03, 0x0022, 0x0006 },
{ 0x04, 0x00, -1, 0x03, 0x0022, 0x0007 },
{ 0x04, 0x00, -1, 0x03, 0x0022, 0x0008 },
{ 0x04, 0x00, -1, 0x03, 0x0022, 0x0009 },
{ 0x04, 0x00, -1, 0x00, 0x0032, 0x0002 },
{ 0x04, 0x00, -1, 0x01, 0x0032, 0x0003 },
{ 0x04, 0x00, -1, 0x02, 0x0032, 0x0004 },
{ 0x04, 0x00, -1, 0x03, 0x0032, 0x0005 },
{ 0x04, 0x00, -1, 0x03, 0x0032, 0x0006 },
{ 0x04, 0x00, -1, 0x03, 0x0032, 0x0007 },
{ 0x04, 0x00, -1, 0x03, 0x0032, 0x0008 },
{ 0x04, 0x00, -1, 0x03, 0x0032, 0x0009 },
{ 0x05, 0x00, -1, 0x00, 0x0042, 0x0002 },
{ 0x05, 0x00, -1, 0x01, 0x0042, 0x0003 },
{ 0x05, 0x00, -1, 0x02, 0x0042, 0x0004 },
{ 0x05, 0x00, -1, 0x03, 0x0042, 0x0005 },
{ 0x05, 0x00, -1, 0x03, 0x0042, 0x0006 },
{ 0x05, 0x00, -1, 0x03, 0x0042, 0x0007 },
{ 0x05, 0x00, -1, 0x03, 0x0042, 0x0008 },
{ 0x05, 0x00, -1, 0x03, 0x0042, 0x0009 },
{ 0x05, 0x00, -1, 0x00, 0x0062, 0x0002 },
{ 0x05, 0x00, -1, 0x01, 0x0062, 0x0003 },
{ 0x05, 0x00, -1, 0x02, 0x0062, 0x0004 },
{ 0x05, 0x00, -1, 0x03, 0x0062, 0x0005 },
{ 0x05, 0x00, -1, 0x03, 0x0062, 0x0006 },
{ 0x05, 0x00, -1, 0x03, 0x0062, 0x0007 },
{ 0x05, 0x00, -1, 0x03, 0x0062, 0x0008 },
{ 0x05, 0x00, -1, 0x03, 0x0062, 0x0009 },
{ 0x02, 0x01, -1, 0x03, 0x000a, 0x000a },
{ 0x02, 0x01, -1, 0x03, 0x000a, 0x000c },
{ 0x02, 0x02, -1, 0x03, 0x000a, 0x000e },
{ 0x02, 0x02, -1, 0x03, 0x000a, 0x0012 },
{ 0x02, 0x03, -1, 0x03, 0x000a, 0x0016 },
{ 0x02, 0x03, -1, 0x03, 0x000a, 0x001e },
{ 0x02, 0x04, -1, 0x03, 0x000a, 0x0026 },
{ 0x02, 0x04, -1, 0x03, 0x000a, 0x0036 },
{ 0x02, 0x01, -1, 0x03, 0x000e, 0x000a },
{ 0x02, 0x01, -1, 0x03, 0x000e, 0x000c },
{ 0x02, 0x02, -1, 0x03, 0x000e, 0x000e },
{ 0x02, 0x02, -1, 0x03, 0x000e, 0x0012 },
{ 0x02, 0x03, -1, 0x03, 0x000e, 0x0016 },
{ 0x02, 0x03, -1, 0x03, 0x000e, 0x001e },
{ 0x02, 0x04, -1, 0x03, 0x000e, 0x0026 },
{ 0x02, 0x04, -1, 0x03, 0x000e, 0x0036 },
{ 0x03, 0x01, -1, 0x03, 0x0012, 0x000a },
{ 0x03, 0x01, -1, 0x03, 0x0012, 0x000c },
{ 0x03, 0x02, -1, 0x03, 0x0012, 0x000e },
{ 0x03, 0x02, -1, 0x03, 0x0012, 0x0012 },
{ 0x03, 0x03, -1, 0x03, 0x0012, 0x0016 },
{ 0x03, 0x03, -1, 0x03, 0x0012, 0x001e },
{ 0x03, 0x04, -1, 0x03, 0x0012, 0x0026 },
{ 0x03, 0x04, -1, 0x03, 0x0012, 0x0036 },
{ 0x03, 0x01, -1, 0x03, 0x001a, 0x000a },
{ 0x03, 0x01, -1, 0x03, 0x001a, 0x000c },
{ 0x03, 0x02, -1, 0x03, 0x001a, 0x000e },
{ 0x03, 0x02, -1, 0x03, 0x001a, 0x0012 },
{ 0x03, 0x03, -1, 0x03, 0x001a, 0x0016 },
{ 0x03, 0x03, -1, 0x03, 0x001a, 0x001e },
{ 0x03, 0x04, -1, 0x03, 0x001a, 0x0026 },
{ 0x03, 0x04, -1, 0x03, 0x001a, 0x0036 },
{ 0x04, 0x01, -1, 0x03, 0x0022, 0x000a },
{ 0x04, 0x01, -1, 0x03, 0x0022, 0x000c },
{ 0x04, 0x02, -1, 0x03, 0x0022, 0x000e },
{ 0x04, 0x02, -1, 0x03, 0x0022, 0x0012 },
{ 0x04, 0x03, -1, 0x03, 0x0022, 0x0016 },
{ 0x04, 0x03, -1, 0x03, 0x0022, 0x001e },
{ 0x04, 0x04, -1, 0x03, 0x0022, 0x0026 },
{ 0x04, 0x04, -1, 0x03, 0x0022, 0x0036 },
{ 0x04, 0x01, -1, 0x03, 0x0032, 0x000a },
{ 0x04, 0x01, -1, 0x03, 0x0032, 0x000c },
{ 0x04, 0x02, -1, 0x03, 0x0032, 0x000e },
{ 0x04, 0x02, -1, 0x03, 0x0032, 0x0012 },
{ 0x04, 0x03, -1, 0x03, 0x0032, 0x0016 },
{ 0x04, 0x03, -1, 0x03, 0x0032, 0x001e },
{ 0x04, 0x04, -1, 0x03, 0x0032, 0x0026 },
{ 0x04, 0x04, -1, 0x03, 0x0032, 0x0036 },
{ 0x05, 0x01, -1, 0x03, 0x0042, 0x000a },
{ 0x05, 0x01, -1, 0x03, 0x0042, 0x000c },
{ 0x05, 0x02, -1, 0x03, 0x0042, 0x000e },
{ 0x05, 0x02, -1, 0x03, 0x0042, 0x0012 },
{ 0x05, 0x03, -1, 0x03, 0x0042, 0x0016 },
{ 0x05, 0x03, -1, 0x03, 0x0042, 0x001e },
{ 0x05, 0x04, -1, 0x03, 0x0042, 0x0026 },
{ 0x05, 0x04, -1, 0x03, 0x0042, 0x0036 },
{ 0x05, 0x01, -1, 0x03, 0x0062, 0x000a },
{ 0x05, 0x01, -1, 0x03, 0x0062, 0x000c },
{ 0x05, 0x02, -1, 0x03, 0x0062, 0x000e },
{ 0x05, 0x02, -1, 0x03, 0x0062, 0x0012 },
{ 0x05, 0x03, -1, 0x03, 0x0062, 0x0016 },
{ 0x05, 0x03, -1, 0x03, 0x0062, 0x001e },
{ 0x05, 0x04, -1, 0x03, 0x0062, 0x0026 },
{ 0x05, 0x04, -1, 0x03, 0x0062, 0x0036 },
{ 0x00, 0x05, -1, 0x03, 0x0000, 0x0046 },
{ 0x00, 0x05, -1, 0x03, 0x0000, 0x0066 },
{ 0x00, 0x06, -1, 0x03, 0x0000, 0x0086 },
{ 0x00, 0x07, -1, 0x03, 0x0000, 0x00c6 },
{ 0x00, 0x08, -1, 0x03, 0x0000, 0x0146 },
{ 0x00, 0x09, -1, 0x03, 0x0000, 0x0246 },
{ 0x00, 0x0a, -1, 0x03, 0x0000, 0x0446 },
{ 0x00, 0x18, -1, 0x03, 0x0000, 0x0846 },
{ 0x00, 0x05, -1, 0x03, 0x0001, 0x0046 },
{ 0x00, 0x05, -1, 0x03, 0x0001, 0x0066 },
{ 0x00, 0x06, -1, 0x03, 0x0001, 0x0086 },
{ 0x00, 0x07, -1, 0x03, 0x0001, 0x00c6 },
{ 0x00, 0x08, -1, 0x03, 0x0001, 0x0146 },
{ 0x00, 0x09, -1, 0x03, 0x0001, 0x0246 },
{ 0x00, 0x0a, -1, 0x03, 0x0001, 0x0446 },
{ 0x00, 0x18, -1, 0x03, 0x0001, 0x0846 },
{ 0x00, 0x05, -1, 0x03, 0x0002, 0x0046 },
{ 0x00, 0x05, -1, 0x03, 0x0002, 0x0066 },
{ 0x00, 0x06, -1, 0x03, 0x0002, 0x0086 },
{ 0x00, 0x07, -1, 0x03, 0x0002, 0x00c6 },
{ 0x00, 0x08, -1, 0x03, 0x0002, 0x0146 },
{ 0x00, 0x09, -1, 0x03, 0x0002, 0x0246 },
{ 0x00, 0x0a, -1, 0x03, 0x0002, 0x0446 },
{ 0x00, 0x18, -1, 0x03, 0x0002, 0x0846 },
{ 0x00, 0x05, -1, 0x03, 0x0003, 0x0046 },
{ 0x00, 0x05, -1, 0x03, 0x0003, 0x0066 },
{ 0x00, 0x06, -1, 0x03, 0x0003, 0x0086 },
{ 0x00, 0x07, -1, 0x03, 0x0003, 0x00c6 },
{ 0x00, 0x08, -1, 0x03, 0x0003, 0x0146 },
{ 0x00, 0x09, -1, 0x03, 0x0003, 0x0246 },
{ 0x00, 0x0a, -1, 0x03, 0x0003, 0x0446 },
{ 0x00, 0x18, -1, 0x03, 0x0003, 0x0846 },
{ 0x00, 0x05, -1, 0x03, 0x0004, 0x0046 },
{ 0x00, 0x05, -1, 0x03, 0x0004, 0x0066 },
{ 0x00, 0x06, -1, 0x03, 0x0004, 0x0086 },
{ 0x00, 0x07, -1, 0x03, 0x0004, 0x00c6 },
{ 0x00, 0x08, -1, 0x03, 0x0004, 0x0146 },
{ 0x00, 0x09, -1, 0x03, 0x0004, 0x0246 },
{ 0x00, 0x0a, -1, 0x03, 0x0004, 0x0446 },
{ 0x00, 0x18, -1, 0x03, 0x0004, 0x0846 },
{ 0x00, 0x05, -1, 0x03, 0x0005, 0x0046 },
{ 0x00, 0x05, -1, 0x03, 0x0005, 0x0066 },
{ 0x00, 0x06, -1, 0x03, 0x0005, 0x0086 },
{ 0x00, 0x07, -1, 0x03, 0x0005, 0x00c6 },
{ 0x00, 0x08, -1, 0x03, 0x0005, 0x0146 },
{ 0x00, 0x09, -1, 0x03, 0x0005, 0x0246 },
{ 0x00, 0x0a, -1, 0x03, 0x0005, 0x0446 },
{ 0x00, 0x18, -1, 0x03, 0x0005, 0x0846 },
{ 0x01, 0x05, -1, 0x03, 0x0006, 0x0046 },
{ 0x01, 0x05, -1, 0x03, 0x0006, 0x0066 },
{ 0x01, 0x06, -1, 0x03, 0x0006, 0x0086 },
{ 0x01, 0x07, -1, 0x03, 0x0006, 0x00c6 },
{ 0x01, 0x08, -1, 0x03, 0x0006, 0x0146 },
{ 0x01, 0x09, -1, 0x03, 0x0006, 0x0246 },
{ 0x01, 0x0a, -1, 0x03, 0x0006, 0x0446 },
{ 0x01, 0x18, -1, 0x03, 0x0006, 0x0846 },
{ 0x01, 0x05, -1, 0x03, 0x0008, 0x0046 },
{ 0x01, 0x05, -1, 0x03, 0x0008, 0x0066 },
{ 0x01, 0x06, -1, 0x03, 0x0008, 0x0086 },
{ 0x01, 0x07, -1, 0x03, 0x0008, 0x00c6 },
{ 0x01, 0x08, -1, 0x03, 0x0008, 0x0146 },
{ 0x01, 0x09, -1, 0x03, 0x0008, 0x0246 },
{ 0x01, 0x0a, -1, 0x03, 0x0008, 0x0446 },
{ 0x01, 0x18, -1, 0x03, 0x0008, 0x0846 },
{ 0x06, 0x00, -1, 0x00, 0x0082, 0x0002 },
{ 0x06, 0x00, -1, 0x01, 0x0082, 0x0003 },
{ 0x06, 0x00, -1, 0x02, 0x0082, 0x0004 },
{ 0x06, 0x00, -1, 0x03, 0x0082, 0x0005 },
{ 0x06, 0x00, -1, 0x03, 0x0082, 0x0006 },
{ 0x06, 0x00, -1, 0x03, 0x0082, 0x0007 },
{ 0x06, 0x00, -1, 0x03, 0x0082, 0x0008 },
{ 0x06, 0x00, -1, 0x03, 0x0082, 0x0009 },
{ 0x07, 0x00, -1, 0x00, 0x00c2, 0x0002 },
{ 0x07, 0x00, -1, 0x01, 0x00c2, 0x0003 },
{ 0x07, 0x00, -1, 0x02, 0x00c2, 0x0004 },
{ 0x07, 0x00, -1, 0x03, 0x00c2, 0x0005 },
{ 0x07, 0x00, -1, 0x03, 0x00c2, 0x0006 },
{ 0x07, 0x00, -1, 0x03, 0x00c2, 0x0007 },
{ 0x07, 0x00, -1, 0x03, 0x00c2, 0x0008 },
{ 0x07, 0x00, -1, 0x03, 0x00c2, 0x0009 },
{ 0x08, 0x00, -1, 0x00, 0x0142, 0x0002 },
{ 0x08, 0x00, -1, 0x01, 0x0142, 0x0003 },
{ 0x08, 0x00, -1, 0x02, 0x0142, 0x0004 },
{ 0x08, 0x00, -1, 0x03, 0x0142, 0x0005 },
{ 0x08, 0x00, -1, 0x03, 0x0142, 0x0006 },
{ 0x08, 0x00, -1, 0x03, 0x0142, 0x0007 },
{ 0x08, 0x00, -1, 0x03, 0x0142, 0x0008 },
{ 0x08, 0x00, -1, 0x03, 0x0142, 0x0009 },
{ 0x09, 0x00, -1, 0x00, 0x0242, 0x0002 },
{ 0x09, 0x00, -1, 0x01, 0x0242, 0x0003 },
{ 0x09, 0x00, -1, 0x02, 0x0242, 0x0004 },
{ 0x09, 0x00, -1, 0x03, 0x0242, 0x0005 },
{ 0x09, 0x00, -1, 0x03, 0x0242, 0x0006 },
{ 0x09, 0x00, -1, 0x03, 0x0242, 0x0007 },
{ 0x09, 0x00, -1, 0x03, 0x0242, 0x0008 },
{ 0x09, 0x00, -1, 0x03, 0x0242, 0x0009 },
{ 0x0a, 0x00, -1, 0x00, 0x0442, 0x0002 },
{ 0x0a, 0x00, -1, 0x01, 0x0442, 0x0003 },
{ 0x0a, 0x00, -1, 0x02, 0x0442, 0x0004 },
{ 0x0a, 0x00, -1, 0x03, 0x0442, 0x0005 },
{ 0x0a, 0x00, -1, 0x03, 0x0442, 0x0006 },
{ 0x0a, 0x00, -1, 0x03, 0x0442, 0x0007 },
{ 0x0a, 0x00, -1, 0x03, 0x0442, 0x0008 },
{ 0x0a, 0x00, -1, 0x03, 0x0442, 0x0009 },
{ 0x0c, 0x00, -1, 0x00, 0x0842, 0x0002 },
{ 0x0c, 0x00, -1, 0x01, 0x0842, 0x0003 },
{ 0x0c, 0x00, -1, 0x02, 0x0842, 0x0004 },
{ 0x0c, 0x00, -1, 0x03, 0x0842, 0x0005 },
{ 0x0c, 0x00, -1, 0x03, 0x0842, 0x0006 },
{ 0x0c, 0x00, -1, 0x03, 0x0842, 0x0007 },
{ 0x0c, 0x00, -1, 0x03, 0x0842, 0x0008 },
{ 0x0c, 0x00, -1, 0x03, 0x0842, 0x0009 },
{ 0x0e, 0x00, -1, 0x00, 0x1842, 0x0002 },
{ 0x0e, 0x00, -1, 0x01, 0x1842, 0x0003 },
{ 0x0e, 0x00, -1, 0x02, 0x1842, 0x0004 },
{ 0x0e, 0x00, -1, 0x03, 0x1842, 0x0005 },
{ 0x0e, 0x00, -1, 0x03, 0x1842, 0x0006 },
{ 0x0e, 0x00, -1, 0x03, 0x1842, 0x0007 },
{ 0x0e, 0x00, -1, 0x03, 0x1842, 0x0008 },
{ 0x0e, 0x00, -1, 0x03, 0x1842, 0x0009 },
{ 0x18, 0x00, -1, 0x00, 0x5842, 0x0002 },
{ 0x18, 0x00, -1, 0x01, 0x5842, 0x0003 },
{ 0x18, 0x00, -1, 0x02, 0x5842, 0x0004 },
{ 0x18, 0x00, -1, 0x03, 0x5842, 0x0005 },
{ 0x18, 0x00, -1, 0x03, 0x5842, 0x0006 },
{ 0x18, 0x00, -1, 0x03, 0x5842, 0x0007 },
{ 0x18, 0x00, -1, 0x03, 0x5842, 0x0008 },
{ 0x18, 0x00, -1, 0x03, 0x5842, 0x0009 },
{ 0x02, 0x05, -1, 0x03, 0x000a, 0x0046 },
{ 0x02, 0x05, -1, 0x03, 0x000a, 0x0066 },
{ 0x02, 0x06, -1, 0x03, 0x000a, 0x0086 },
{ 0x02, 0x07, -1, 0x03, 0x000a, 0x00c6 },
{ 0x02, 0x08, -1, 0x03, 0x000a, 0x0146 },
{ 0x02, 0x09, -1, 0x03, 0x000a, 0x0246 },
{ 0x02, 0x0a, -1, 0x03, 0x000a, 0x0446 },
{ 0x02, 0x18, -1, 0x03, 0x000a, 0x0846 },
{ 0x02, 0x05, -1, 0x03, 0x000e, 0x0046 },
{ 0x02, 0x05, -1, 0x03, 0x000e, 0x0066 },
{ 0x02, 0x06, -1, 0x03, 0x000e, 0x0086 },
{ 0x02, 0x07, -1, 0x03, 0x000e, 0x00c6 },
{ 0x02, 0x08, -1, 0x03, 0x000e, 0x0146 },
{ 0x02, 0x09, -1, 0x03, 0x000e, 0x0246 },
{ 0x02, 0x0a, -1, 0x03, 0x000e, 0x0446 },
{ 0x02, 0x18, -1, 0x03, 0x000e, 0x0846 },
{ 0x03, 0x05, -1, 0x03, 0x0012, 0x0046 },
{ 0x03, 0x05, -1, 0x03, 0x0012, 0x0066 },
{ 0x03, 0x06, -1, 0x03, 0x0012, 0x0086 },
{ 0x03, 0x07, -1, 0x03, 0x0012, 0x00c6 },
{ 0x03, 0x08, -1, 0x03, 0x0012, 0x0146 },
{ 0x03, 0x09, -1, 0x03, 0x0012, 0x0246 },
{ 0x03, 0x0a, -1, 0x03, 0x0012, 0x0446 },
{ 0x03, 0x18, -1, 0x03, 0x0012, 0x0846 },
{ 0x03, 0x05, -1, 0x03, 0x001a, 0x0046 },
{ 0x03, 0x05, -1, 0x03, 0x001a, 0x0066 },
{ 0x03, 0x06, -1, 0x03, 0x001a, 0x0086 },
{ 0x03, 0x07, -1, 0x03, 0x001a, 0x00c6 },
{ 0x03, 0x08, -1, 0x03, 0x001a, 0x0146 },
{ 0x03, 0x09, -1, 0x03, 0x001a, 0x0246 },
{ 0x03, 0x0a, -1, 0x03, 0x001a, 0x0446 },
{ 0x03, 0x18, -1, 0x03, 0x001a, 0x0846 },
{ 0x04, 0x05, -1, 0x03, 0x0022, 0x0046 },
{ 0x04, 0x05, -1, 0x03, 0x0022, 0x0066 },
{ 0x04, 0x06, -1, 0x03, 0x0022, 0x0086 },
{ 0x04, 0x07, -1, 0x03, 0x0022, 0x00c6 },
{ 0x04, 0x08, -1, 0x03, 0x0022, 0x0146 },
{ 0x04, 0x09, -1, 0x03, 0x0022, 0x0246 },
{ 0x04, 0x0a, -1, 0x03, 0x0022, 0x0446 },
{ 0x04, 0x18, -1, 0x03, 0x0022, 0x0846 },
{ 0x04, 0x05, -1, 0x03, 0x0032, 0x0046 },
{ 0x04, 0x05, -1, 0x03, 0x0032, 0x0066 },
{ 0x04, 0x06, -1, 0x03, 0x0032, 0x0086 },
{ 0x04, 0x07, -1, 0x03, 0x0032, 0x00c6 },
{ 0x04, 0x08, -1, 0x03, 0x0032, 0x0146 },
{ 0x04, 0x09, -1, 0x03, 0x0032, 0x0246 },
{ 0x04, 0x0a, -1, 0x03, 0x0032, 0x0446 },
{ 0x04, 0x18, -1, 0x03, 0x0032, 0x0846 },
{ 0x05, 0x05, -1, 0x03, 0x0042, 0x0046 },
{ 0x05, 0x05, -1, 0x03, 0x0042, 0x0066 },
{ 0x05, 0x06, -1, 0x03, 0x0042, 0x0086 },
{ 0x05, 0x07, -1, 0x03, 0x0042, 0x00c6 },
{ 0x05, 0x08, -1, 0x03, 0x0042, 0x0146 },
{ 0x05, 0x09, -1, 0x03, 0x0042, 0x0246 },
{ 0x05, 0x0a, -1, 0x03, 0x0042, 0x0446 },
{ 0x05, 0x18, -1, 0x03, 0x0042, 0x0846 },
{ 0x05, 0x05, -1, 0x03, 0x0062, 0x0046 },
{ 0x05, 0x05, -1, 0x03, 0x0062, 0x0066 },
{ 0x05, 0x06, -1, 0x03, 0x0062, 0x0086 },
{ 0x05, 0x07, -1, 0x03, 0x0062, 0x00c6 },
{ 0x05, 0x08, -1, 0x03, 0x0062, 0x0146 },
{ 0x05, 0x09, -1, 0x03, 0x0062, 0x0246 },
{ 0x05, 0x0a, -1, 0x03, 0x0062, 0x0446 },
{ 0x05, 0x18, -1, 0x03, 0x0062, 0x0846 },
{ 0x06, 0x01, -1, 0x03, 0x0082, 0x000a },
{ 0x06, 0x01, -1, 0x03, 0x0082, 0x000c },
{ 0x06, 0x02, -1, 0x03, 0x0082, 0x000e },
{ 0x06, 0x02, -1, 0x03, 0x0082, 0x0012 },
{ 0x06, 0x03, -1, 0x03, 0x0082, 0x0016 },
{ 0x06, 0x03, -1, 0x03, 0x0082, 0x001e },
{ 0x06, 0x04, -1, 0x03, 0x0082, 0x0026 },
{ 0x06, 0x04, -1, 0x03, 0x0082, 0x0036 },
{ 0x07, 0x01, -1, 0x03, 0x00c2, 0x000a },
{ 0x07, 0x01, -1, 0x03, 0x00c2, 0x000c },
{ 0x07, 0x02, -1, 0x03, 0x00c2, 0x000e },
{ 0x07, 0x02, -1, 0x03, 0x00c2, 0x0012 },
{ 0x07, 0x03, -1, 0x03, 0x00c2, 0x0016 },
{ 0x07, 0x03, -1, 0x03, 0x00c2, 0x001e },
{ 0x07, 0x04, -1, 0x03, 0x00c2, 0x0026 },
{ 0x07, 0x04, -1, 0x03, 0x00c2, 0x0036 },
{ 0x08, 0x01, -1, 0x03, 0x0142, 0x000a },
{ 0x08, 0x01, -1, 0x03, 0x0142, 0x000c },
{ 0x08, 0x02, -1, 0x03, 0x0142, 0x000e },
{ 0x08, 0x02, -1, 0x03, 0x0142, 0x0012 },
{ 0x08, 0x03, -1, 0x03, 0x0142, 0x0016 },
{ 0x08, 0x03, -1, 0x03, 0x0142, 0x001e },
{ 0x08, 0x04, -1, 0x03, 0x0142, 0x0026 },
{ 0x08, 0x04, -1, 0x03, 0x0142, 0x0036 },
{ 0x09, 0x01, -1, 0x03, 0x0242, 0x000a },
{ 0x09, 0x01, -1, 0x03, 0x0242, 0x000c },
{ 0x09, 0x02, -1, 0x03, 0x0242, 0x000e },
{ 0x09, 0x02, -1, 0x03, 0x0242, 0x0012 },
{ 0x09, 0x03, -1, 0x03, 0x0242, 0x0016 },
{ 0x09, 0x03, -1, 0x03, 0x0242, 0x001e },
{ 0x09, 0x04, -1, 0x03, 0x0242, 0x0026 },
{ 0x09, 0x04, -1, 0x03, 0x0242, 0x0036 },
{ 0x0a, 0x01, -1, 0x03, 0x0442, 0x000a },
{ 0x0a, 0x01, -1, 0x03, 0x0442, 0x000c },
{ 0x0a, 0x02, -1, 0x03, 0x0442, 0x000e },
{ 0x0a, 0x02, -1, 0x03, 0x0442, 0x0012 },
{ 0x0a, 0x03, -1, 0x03, 0x0442, 0x0016 },
{ 0x0a, 0x03, -1, 0x03, 0x0442, 0x001e },
{ 0x0a, 0x04, -1, 0x03, 0x0442, 0x0026 },
{ 0x0a, 0x04, -1, 0x03, 0x0442, 0x0036 },
{ 0x0c, 0x01, -1, 0x03, 0x0842, 0x000a },
{ 0x0c, 0x01, -1, 0x03, 0x0842, 0x000c },
{ 0x0c, 0x02, -1, 0x03, 0x0842, 0x000e },
{ 0x0c, 0x02, -1, 0x03, 0x0842, 0x0012 },
{ 0x0c, 0x03, -1, 0x03, 0x0842, 0x0016 },
{ 0x0c, 0x03, -1, 0x03, 0x0842, 0x001e },
{ 0x0c, 0x04, -1, 0x03, 0x0842, 0x0026 },
{ 0x0c, 0x04, -1, 0x03, 0x0842, 0x0036 },
{ 0x0e, 0x01, -1, 0x03, 0x1842, 0x000a },
{ 0x0e, 0x01, -1, 0x03, 0x1842, 0x000c },
{ 0x0e, 0x02, -1, 0x03, 0x1842, 0x000e },
{ 0x0e, 0x02, -1, 0x03, 0x1842, 0x0012 },
{ 0x0e, 0x03, -1, 0x03, 0x1842, 0x0016 },
{ 0x0e, 0x03, -1, 0x03, 0x1842, 0x001e },
{ 0x0e, 0x04, -1, 0x03, 0x1842, 0x0026 },
{ 0x0e, 0x04, -1, 0x03, 0x1842, 0x0036 },
{ 0x18, 0x01, -1, 0x03, 0x5842, 0x000a },
{ 0x18, 0x01, -1, 0x03, 0x5842, 0x000c },
{ 0x18, 0x02, -1, 0x03, 0x5842, 0x000e },
{ 0x18, 0x02, -1, 0x03, 0x5842, 0x0012 },
{ 0x18, 0x03, -1, 0x03, 0x5842, 0x0016 },
{ 0x18, 0x03, -1, 0x03, 0x5842, 0x001e },
{ 0x18, 0x04, -1, 0x03, 0x5842, 0x0026 },
{ 0x18, 0x04, -1, 0x03, 0x5842, 0x0036 },
{ 0x06, 0x05, -1, 0x03, 0x0082, 0x0046 },
{ 0x06, 0x05, -1, 0x03, 0x0082, 0x0066 },
{ 0x06, 0x06, -1, 0x03, 0x0082, 0x0086 },
{ 0x06, 0x07, -1, 0x03, 0x0082, 0x00c6 },
{ 0x06, 0x08, -1, 0x03, 0x0082, 0x0146 },
{ 0x06, 0x09, -1, 0x03, 0x0082, 0x0246 },
{ 0x06, 0x0a, -1, 0x03, 0x0082, 0x0446 },
{ 0x06, 0x18, -1, 0x03, 0x0082, 0x0846 },
{ 0x07, 0x05, -1, 0x03, 0x00c2, 0x0046 },
{ 0x07, 0x05, -1, 0x03, 0x00c2, 0x0066 },
{ 0x07, 0x06, -1, 0x03, 0x00c2, 0x0086 },
{ 0x07, 0x07, -1, 0x03, 0x00c2, 0x00c6 },
{ 0x07, 0x08, -1, 0x03, 0x00c2, 0x0146 },
{ 0x07, 0x09, -1, 0x03, 0x00c2, 0x0246 },
{ 0x07, 0x0a, -1, 0x03, 0x00c2, 0x0446 },
{ 0x07, 0x18, -1, 0x03, 0x00c2, 0x0846 },
{ 0x08, 0x05, -1, 0x03, 0x0142, 0x0046 },
{ 0x08, 0x05, -1, 0x03, 0x0142, 0x0066 },
{ 0x08, 0x06, -1, 0x03, 0x0142, 0x0086 },
{ 0x08, 0x07, -1, 0x03, 0x0142, 0x00c6 },
{ 0x08, 0x08, -1, 0x03, 0x0142, 0x0146 },
{ 0x08, 0x09, -1, 0x03, 0x0142, 0x0246 },
{ 0x08, 0x0a, -1, 0x03, 0x0142, 0x0446 },
{ 0x08, 0x18, -1, 0x03, 0x0142, 0x0846 },
{ 0x09, 0x05, -1, 0x03, 0x0242, 0x0046 },
{ 0x09, 0x05, -1, 0x03, 0x0242, 0x0066 },
{ 0x09, 0x06, -1, 0x03, 0x0242, 0x0086 },
{ 0x09, 0x07, -1, 0x03, 0x0242, 0x00c6 },
{ 0x09, 0x08, -1, 0x03, 0x0242, 0x0146 },
{ 0x09, 0x09, -1, 0x03, 0x0242, 0x0246 },
{ 0x09, 0x0a, -1, 0x03, 0x0242, 0x0446 },
{ 0x09, 0x18, -1, 0x03, 0x0242, 0x0846 },
{ 0x0a, 0x05, -1, 0x03, 0x0442, 0x0046 },
{ 0x0a, 0x05, -1, 0x03, 0x0442, 0x0066 },
{ 0x0a, 0x06, -1, 0x03, 0x0442, 0x0086 },
{ 0x0a, 0x07, -1, 0x03, 0x0442, 0x00c6 },
{ 0x0a, 0x08, -1, 0x03, 0x0442, 0x0146 },
{ 0x0a, 0x09, -1, 0x03, 0x0442, 0x0246 },
{ 0x0a, 0x0a, -1, 0x03, 0x0442, 0x0446 },
{ 0x0a, 0x18, -1, 0x03, 0x0442, 0x0846 },
{ 0x0c, 0x05, -1, 0x03, 0x0842, 0x0046 },
{ 0x0c, 0x05, -1, 0x03, 0x0842, 0x0066 },
{ 0x0c, 0x06, -1, 0x03, 0x0842, 0x0086 },
{ 0x0c, 0x07, -1, 0x03, 0x0842, 0x00c6 },
{ 0x0c, 0x08, -1, 0x03, 0x0842, 0x0146 },
{ 0x0c, 0x09, -1, 0x03, 0x0842, 0x0246 },
{ 0x0c, 0x0a, -1, 0x03, 0x0842, 0x0446 },
{ 0x0c, 0x18, -1, 0x03, 0x0842, 0x0846 },
{ 0x0e, 0x05, -1, 0x03, 0x1842, 0x0046 },
{ 0x0e, 0x05, -1, 0x03, 0x1842, 0x0066 },
{ 0x0e, 0x06, -1, 0x03, 0x1842, 0x0086 },
{ 0x0e, 0x07, -1, 0x03, 0x1842, 0x00c6 },
{ 0x0e, 0x08, -1, 0x03, 0x1842, 0x0146 },
{ 0x0e, 0x09, -1, 0x03, 0x1842, 0x0246 },
{ 0x0e, 0x0a, -1, 0x03, 0x1842, 0x0446 },
{ 0x0e, 0x18, -1, 0x03, 0x1842, 0x0846 },
{ 0x18, 0x05, -1, 0x03, 0x5842, 0x0046 },
{ 0x18, 0x05, -1, 0x03, 0x5842, 0x0066 },
{ 0x18, 0x06, -1, 0x03, 0x5842, 0x0086 },
{ 0x18, 0x07, -1, 0x03, 0x5842, 0x00c6 },
{ 0x18, 0x08, -1, 0x03, 0x5842, 0x0146 },
{ 0x18, 0x09, -1, 0x03, 0x5842, 0x0246 },
{ 0x18, 0x0a, -1, 0x03, 0x5842, 0x0446 },
{ 0x18, 0x18, -1, 0x03, 0x5842, 0x0846 },
};
#endif /* BROTLI_DEC_PREFIX_H_ */

View File

@ -1,183 +0,0 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
#include "state.h"
#include <stdlib.h> /* free, malloc */
#include <brotli/types.h>
#include "../common/dictionary.h"
#include "huffman.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
if (!alloc_func) {
s->alloc_func = BrotliDefaultAllocFunc;
s->free_func = BrotliDefaultFreeFunc;
s->memory_manager_opaque = 0;
} else {
s->alloc_func = alloc_func;
s->free_func = free_func;
s->memory_manager_opaque = opaque;
}
s->error_code = 0; /* BROTLI_DECODER_NO_ERROR */
BrotliInitBitReader(&s->br);
s->state = BROTLI_STATE_UNINITED;
s->large_window = 0;
s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
s->buffer_length = 0;
s->loop_counter = 0;
s->pos = 0;
s->rb_roundtrips = 0;
s->partial_pos_out = 0;
s->used_input = 0;
s->block_type_trees = NULL;
s->block_len_trees = NULL;
s->ringbuffer = NULL;
s->ringbuffer_size = 0;
s->new_ringbuffer_size = 0;
s->ringbuffer_mask = 0;
s->context_map = NULL;
s->context_modes = NULL;
s->dist_context_map = NULL;
s->context_map_slice = NULL;
s->dist_context_map_slice = NULL;
s->literal_hgroup.codes = NULL;
s->literal_hgroup.htrees = NULL;
s->insert_copy_hgroup.codes = NULL;
s->insert_copy_hgroup.htrees = NULL;
s->distance_hgroup.codes = NULL;
s->distance_hgroup.htrees = NULL;
s->is_last_metablock = 0;
s->is_uncompressed = 0;
s->is_metadata = 0;
s->should_wrap_ringbuffer = 0;
s->canny_ringbuffer_allocation = 1;
s->window_bits = 0;
s->max_distance = 0;
s->dist_rb[0] = 16;
s->dist_rb[1] = 15;
s->dist_rb[2] = 11;
s->dist_rb[3] = 4;
s->dist_rb_idx = 0;
s->block_type_trees = NULL;
s->block_len_trees = NULL;
s->mtf_upper_bound = 63;
s->compound_dictionary = NULL;
s->dictionary =
BrotliSharedDictionaryCreateInstance(alloc_func, free_func, opaque);
if (!s->dictionary) return BROTLI_FALSE;
s->metadata_start_func = NULL;
s->metadata_chunk_func = NULL;
s->metadata_callback_opaque = 0;
return BROTLI_TRUE;
}
void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
s->meta_block_remaining_len = 0;
s->block_length[0] = 1U << 24;
s->block_length[1] = 1U << 24;
s->block_length[2] = 1U << 24;
s->num_block_types[0] = 1;
s->num_block_types[1] = 1;
s->num_block_types[2] = 1;
s->block_type_rb[0] = 1;
s->block_type_rb[1] = 0;
s->block_type_rb[2] = 1;
s->block_type_rb[3] = 0;
s->block_type_rb[4] = 1;
s->block_type_rb[5] = 0;
s->context_map = NULL;
s->context_modes = NULL;
s->dist_context_map = NULL;
s->context_map_slice = NULL;
s->literal_htree = NULL;
s->dist_context_map_slice = NULL;
s->dist_htree_index = 0;
s->context_lookup = NULL;
s->literal_hgroup.codes = NULL;
s->literal_hgroup.htrees = NULL;
s->insert_copy_hgroup.codes = NULL;
s->insert_copy_hgroup.htrees = NULL;
s->distance_hgroup.codes = NULL;
s->distance_hgroup.htrees = NULL;
}
void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState* s) {
BROTLI_DECODER_FREE(s, s->context_modes);
BROTLI_DECODER_FREE(s, s->context_map);
BROTLI_DECODER_FREE(s, s->dist_context_map);
BROTLI_DECODER_FREE(s, s->literal_hgroup.htrees);
BROTLI_DECODER_FREE(s, s->insert_copy_hgroup.htrees);
BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees);
}
#ifdef BROTLI_REPORTING
/* When BROTLI_REPORTING is defined extra reporting module have to be linked. */
void BrotliDecoderOnFinish(const BrotliDecoderState* s);
#define BROTLI_DECODER_ON_FINISH(s) BrotliDecoderOnFinish(s);
#else
#if !defined(BROTLI_DECODER_ON_FINISH)
#define BROTLI_DECODER_ON_FINISH(s) (void)(s);
#endif
#endif
void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
BrotliDecoderStateCleanupAfterMetablock(s);
BROTLI_DECODER_ON_FINISH(s);
BROTLI_DECODER_FREE(s, s->compound_dictionary);
BrotliSharedDictionaryDestroyInstance(s->dictionary);
s->dictionary = NULL;
BROTLI_DECODER_FREE(s, s->ringbuffer);
BROTLI_DECODER_FREE(s, s->block_type_trees);
}
BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
HuffmanTreeGroup* group, uint32_t alphabet_size_max,
uint32_t alphabet_size_limit, uint32_t ntrees) {
/* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables)
This number is discovered "unlimited" "enough" calculator; it is actually
a wee bigger than required in several cases (especially for alphabets with
less than 16 symbols). */
const size_t max_table_size = alphabet_size_limit + 376;
const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
/* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */
HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s,
code_size + htree_size);
group->alphabet_size_max = (uint16_t)alphabet_size_max;
group->alphabet_size_limit = (uint16_t)alphabet_size_limit;
group->num_htrees = (uint16_t)ntrees;
group->htrees = p;
group->codes = (HuffmanCode*)(&p[ntrees]);
return !!p;
}
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif

View File

@ -1,389 +0,0 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Brotli state for partial streaming decoding. */
#ifndef BROTLI_DEC_STATE_H_
#define BROTLI_DEC_STATE_H_
#include <brotli/decode.h>
#include <brotli/shared_dictionary.h>
#include <brotli/types.h>
#include "../common/constants.h"
#include "../common/dictionary.h"
#include "../common/platform.h"
#include "../common/transform.h"
#include "bit_reader.h"
#include "huffman.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
/* Graphviz diagram that describes state transitions:
digraph States {
graph [compound=true]
concentrate=true
node [shape="box"]
UNINITED -> {LARGE_WINDOW_BITS -> INITIALIZE}
subgraph cluster_metablock_workflow {
style="rounded"
label=< <B>METABLOCK CYCLE</B> >
METABLOCK_BEGIN -> METABLOCK_HEADER
METABLOCK_HEADER:sw -> METADATA
METABLOCK_HEADER:s -> UNCOMPRESSED
METABLOCK_HEADER:se -> METABLOCK_DONE:ne
METADATA:s -> METABLOCK_DONE:w
UNCOMPRESSED:s -> METABLOCK_DONE:n
METABLOCK_DONE:e -> METABLOCK_BEGIN:e [constraint="false"]
}
INITIALIZE -> METABLOCK_BEGIN
METABLOCK_DONE -> DONE
subgraph cluster_compressed_metablock {
style="rounded"
label=< <B>COMPRESSED METABLOCK</B> >
subgraph cluster_command {
style="rounded"
label=< <B>HOT LOOP</B> >
_METABLOCK_DONE_PORT_ [shape=point style=invis]
{
// Set different shape for nodes returning from "compressed metablock".
node [shape=invhouse]; CMD_INNER CMD_POST_DECODE_LITERALS;
CMD_POST_WRAP_COPY; CMD_INNER_WRITE; CMD_POST_WRITE_1;
}
CMD_BEGIN -> CMD_INNER -> CMD_POST_DECODE_LITERALS -> CMD_POST_WRAP_COPY
// IO ("write") nodes are not in the hot loop!
CMD_INNER_WRITE [style=dashed]
CMD_INNER -> CMD_INNER_WRITE
CMD_POST_WRITE_1 [style=dashed]
CMD_POST_DECODE_LITERALS -> CMD_POST_WRITE_1
CMD_POST_WRITE_2 [style=dashed]
CMD_POST_WRAP_COPY -> CMD_POST_WRITE_2
CMD_POST_WRITE_1 -> CMD_BEGIN:s [constraint="false"]
CMD_INNER_WRITE -> {CMD_INNER CMD_POST_DECODE_LITERALS}
[constraint="false"]
CMD_BEGIN:ne -> CMD_POST_DECODE_LITERALS [constraint="false"]
CMD_POST_WRAP_COPY -> CMD_BEGIN [constraint="false"]
CMD_POST_DECODE_LITERALS -> CMD_BEGIN:ne [constraint="false"]
CMD_POST_WRITE_2 -> CMD_POST_WRAP_COPY [constraint="false"]
{rank=same; CMD_BEGIN; CMD_INNER; CMD_POST_DECODE_LITERALS;
CMD_POST_WRAP_COPY}
{rank=same; CMD_INNER_WRITE; CMD_POST_WRITE_1; CMD_POST_WRITE_2}
{CMD_INNER CMD_POST_DECODE_LITERALS CMD_POST_WRAP_COPY} ->
_METABLOCK_DONE_PORT_ [style=invis]
{CMD_INNER_WRITE CMD_POST_WRITE_1} -> _METABLOCK_DONE_PORT_
[constraint="false" style=invis]
}
BEFORE_COMPRESSED_METABLOCK_HEADER:s -> HUFFMAN_CODE_0:n
HUFFMAN_CODE_0 -> HUFFMAN_CODE_1 -> HUFFMAN_CODE_2 -> HUFFMAN_CODE_3
HUFFMAN_CODE_0 -> METABLOCK_HEADER_2 -> CONTEXT_MODES -> CONTEXT_MAP_1
CONTEXT_MAP_1 -> CONTEXT_MAP_2 -> TREE_GROUP
TREE_GROUP -> BEFORE_COMPRESSED_METABLOCK_BODY:e
BEFORE_COMPRESSED_METABLOCK_BODY:s -> CMD_BEGIN:n
HUFFMAN_CODE_3:e -> HUFFMAN_CODE_0:ne [constraint="false"]
{rank=same; HUFFMAN_CODE_0; HUFFMAN_CODE_1; HUFFMAN_CODE_2; HUFFMAN_CODE_3}
{rank=same; METABLOCK_HEADER_2; CONTEXT_MODES; CONTEXT_MAP_1; CONTEXT_MAP_2;
TREE_GROUP}
}
METABLOCK_HEADER:e -> BEFORE_COMPRESSED_METABLOCK_HEADER:n
_METABLOCK_DONE_PORT_ -> METABLOCK_DONE:se
[constraint="false" ltail=cluster_command]
UNINITED [shape=Mdiamond];
DONE [shape=Msquare];
}
*/
typedef enum {
BROTLI_STATE_UNINITED,
BROTLI_STATE_LARGE_WINDOW_BITS,
BROTLI_STATE_INITIALIZE,
BROTLI_STATE_METABLOCK_BEGIN,
BROTLI_STATE_METABLOCK_HEADER,
BROTLI_STATE_METABLOCK_HEADER_2,
BROTLI_STATE_CONTEXT_MODES,
BROTLI_STATE_COMMAND_BEGIN,
BROTLI_STATE_COMMAND_INNER,
BROTLI_STATE_COMMAND_POST_DECODE_LITERALS,
BROTLI_STATE_COMMAND_POST_WRAP_COPY,
BROTLI_STATE_UNCOMPRESSED,
BROTLI_STATE_METADATA,
BROTLI_STATE_COMMAND_INNER_WRITE,
BROTLI_STATE_METABLOCK_DONE,
BROTLI_STATE_COMMAND_POST_WRITE_1,
BROTLI_STATE_COMMAND_POST_WRITE_2,
BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER,
BROTLI_STATE_HUFFMAN_CODE_0,
BROTLI_STATE_HUFFMAN_CODE_1,
BROTLI_STATE_HUFFMAN_CODE_2,
BROTLI_STATE_HUFFMAN_CODE_3,
BROTLI_STATE_CONTEXT_MAP_1,
BROTLI_STATE_CONTEXT_MAP_2,
BROTLI_STATE_TREE_GROUP,
BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY,
BROTLI_STATE_DONE
} BrotliRunningState;
typedef enum {
BROTLI_STATE_METABLOCK_HEADER_NONE,
BROTLI_STATE_METABLOCK_HEADER_EMPTY,
BROTLI_STATE_METABLOCK_HEADER_NIBBLES,
BROTLI_STATE_METABLOCK_HEADER_SIZE,
BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED,
BROTLI_STATE_METABLOCK_HEADER_RESERVED,
BROTLI_STATE_METABLOCK_HEADER_BYTES,
BROTLI_STATE_METABLOCK_HEADER_METADATA
} BrotliRunningMetablockHeaderState;
typedef enum {
BROTLI_STATE_UNCOMPRESSED_NONE,
BROTLI_STATE_UNCOMPRESSED_WRITE
} BrotliRunningUncompressedState;
typedef enum {
BROTLI_STATE_TREE_GROUP_NONE,
BROTLI_STATE_TREE_GROUP_LOOP
} BrotliRunningTreeGroupState;
typedef enum {
BROTLI_STATE_CONTEXT_MAP_NONE,
BROTLI_STATE_CONTEXT_MAP_READ_PREFIX,
BROTLI_STATE_CONTEXT_MAP_HUFFMAN,
BROTLI_STATE_CONTEXT_MAP_DECODE,
BROTLI_STATE_CONTEXT_MAP_TRANSFORM
} BrotliRunningContextMapState;
typedef enum {
BROTLI_STATE_HUFFMAN_NONE,
BROTLI_STATE_HUFFMAN_SIMPLE_SIZE,
BROTLI_STATE_HUFFMAN_SIMPLE_READ,
BROTLI_STATE_HUFFMAN_SIMPLE_BUILD,
BROTLI_STATE_HUFFMAN_COMPLEX,
BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS
} BrotliRunningHuffmanState;
typedef enum {
BROTLI_STATE_DECODE_UINT8_NONE,
BROTLI_STATE_DECODE_UINT8_SHORT,
BROTLI_STATE_DECODE_UINT8_LONG
} BrotliRunningDecodeUint8State;
typedef enum {
BROTLI_STATE_READ_BLOCK_LENGTH_NONE,
BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
} BrotliRunningReadBlockLengthState;
/* BrotliDecoderState addon, used for Compound Dictionary functionality. */
typedef struct BrotliDecoderCompoundDictionary {
int num_chunks;
int total_size;
int br_index;
int br_offset;
int br_length;
int br_copied;
const uint8_t* chunks[16];
int chunk_offsets[16];
int block_bits;
uint8_t block_map[256];
} BrotliDecoderCompoundDictionary;
typedef struct BrotliMetablockHeaderArena {
BrotliRunningTreeGroupState substate_tree_group;
BrotliRunningContextMapState substate_context_map;
BrotliRunningHuffmanState substate_huffman;
uint32_t sub_loop_counter;
uint32_t repeat_code_len;
uint32_t prev_code_len;
/* For ReadHuffmanCode. */
uint32_t symbol;
uint32_t repeat;
uint32_t space;
/* Huffman table for "histograms". */
HuffmanCode table[32];
/* List of heads of symbol chains. */
uint16_t* symbol_lists;
/* Storage from symbol_lists. */
uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
BROTLI_NUM_COMMAND_SYMBOLS];
/* Tails of symbol chains. */
int next_symbol[32];
uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
/* Population counts for the code lengths. */
uint16_t code_length_histo[16];
/* For HuffmanTreeGroupDecode. */
int htree_index;
HuffmanCode* next;
/* For DecodeContextMap. */
uint32_t context_index;
uint32_t max_run_length_prefix;
uint32_t code;
HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
} BrotliMetablockHeaderArena;
typedef struct BrotliMetablockBodyArena {
uint8_t dist_extra_bits[544];
uint32_t dist_offset[544];
} BrotliMetablockBodyArena;
struct BrotliDecoderStateStruct {
BrotliRunningState state;
/* This counter is reused for several disjoint loops. */
int loop_counter;
BrotliBitReader br;
brotli_alloc_func alloc_func;
brotli_free_func free_func;
void* memory_manager_opaque;
/* Temporary storage for remaining input. Brotli stream format is designed in
a way, that 64 bits are enough to make progress in decoding. */
union {
uint64_t u64;
uint8_t u8[8];
} buffer;
uint32_t buffer_length;
int pos;
int max_backward_distance;
int max_distance;
int ringbuffer_size;
int ringbuffer_mask;
int dist_rb_idx;
int dist_rb[4];
int error_code;
uint8_t* ringbuffer;
uint8_t* ringbuffer_end;
HuffmanCode* htree_command;
const uint8_t* context_lookup;
uint8_t* context_map_slice;
uint8_t* dist_context_map_slice;
/* This ring buffer holds a few past copy distances that will be used by
some special distance codes. */
HuffmanTreeGroup literal_hgroup;
HuffmanTreeGroup insert_copy_hgroup;
HuffmanTreeGroup distance_hgroup;
HuffmanCode* block_type_trees;
HuffmanCode* block_len_trees;
/* This is true if the literal context map histogram type always matches the
block type. It is then not needed to keep the context (faster decoding). */
int trivial_literal_context;
/* Distance context is actual after command is decoded and before distance is
computed. After distance computation it is used as a temporary variable. */
int distance_context;
int meta_block_remaining_len;
uint32_t block_length_index;
uint32_t block_length[3];
uint32_t num_block_types[3];
uint32_t block_type_rb[6];
uint32_t distance_postfix_bits;
uint32_t num_direct_distance_codes;
uint32_t num_dist_htrees;
uint8_t* dist_context_map;
HuffmanCode* literal_htree;
uint8_t dist_htree_index;
int copy_length;
int distance_code;
/* For partial write operations. */
size_t rb_roundtrips; /* how many times we went around the ring-buffer */
size_t partial_pos_out; /* how much output to the user in total */
/* For InverseMoveToFrontTransform. */
uint32_t mtf_upper_bound;
uint32_t mtf[64 + 1];
/* Less used attributes are at the end of this struct. */
brotli_decoder_metadata_start_func metadata_start_func;
brotli_decoder_metadata_chunk_func metadata_chunk_func;
void* metadata_callback_opaque;
/* For reporting. */
uint64_t used_input; /* how many bytes of input are consumed */
/* States inside function calls. */
BrotliRunningMetablockHeaderState substate_metablock_header;
BrotliRunningUncompressedState substate_uncompressed;
BrotliRunningDecodeUint8State substate_decode_uint8;
BrotliRunningReadBlockLengthState substate_read_block_length;
unsigned int is_last_metablock : 1;
unsigned int is_uncompressed : 1;
unsigned int is_metadata : 1;
unsigned int should_wrap_ringbuffer : 1;
unsigned int canny_ringbuffer_allocation : 1;
unsigned int large_window : 1;
unsigned int size_nibbles : 8;
uint32_t window_bits;
int new_ringbuffer_size;
uint32_t num_literal_htrees;
uint8_t* context_map;
uint8_t* context_modes;
BrotliSharedDictionary* dictionary;
BrotliDecoderCompoundDictionary* compound_dictionary;
uint32_t trivial_literal_contexts[8]; /* 256 bits */
union {
BrotliMetablockHeaderArena header;
BrotliMetablockBodyArena body;
} arena;
};
typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal;
#define BrotliDecoderState BrotliDecoderStateInternal
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
BROTLI_INTERNAL void BrotliDecoderStateCleanup(BrotliDecoderState* s);
BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
BrotliDecoderState* s);
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size_max,
uint32_t alphabet_size_limit, uint32_t ntrees);
#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
#define BROTLI_DECODER_FREE(S, X) { \
S->free_func(S->memory_manager_opaque, X); \
X = NULL; \
}
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_DEC_STATE_H_ */

View File

@ -1,409 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/**
* @file
* API for Brotli decompression.
*/
#ifndef BROTLI_DEC_DECODE_H_
#define BROTLI_DEC_DECODE_H_
#include <brotli/port.h>
#include <brotli/shared_dictionary.h>
#include <brotli/types.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
/**
* Opaque structure that holds decoder state.
*
* Allocated and initialized with ::BrotliDecoderCreateInstance.
* Cleaned up and deallocated with ::BrotliDecoderDestroyInstance.
*/
typedef struct BrotliDecoderStateStruct BrotliDecoderState;
/**
* Result type for ::BrotliDecoderDecompress and
* ::BrotliDecoderDecompressStream functions.
*/
typedef enum {
/** Decoding error, e.g. corrupted input or memory allocation problem. */
BROTLI_DECODER_RESULT_ERROR = 0,
/** Decoding successfully completed. */
BROTLI_DECODER_RESULT_SUCCESS = 1,
/** Partially done; should be called again with more input. */
BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT = 2,
/** Partially done; should be called again with more output. */
BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT = 3
} BrotliDecoderResult;
/**
* Template that evaluates items of ::BrotliDecoderErrorCode.
*
* Example: @code {.cpp}
* // Log Brotli error code.
* switch (brotliDecoderErrorCode) {
* #define CASE_(PREFIX, NAME, CODE) \
* case BROTLI_DECODER ## PREFIX ## NAME: \
* LOG(INFO) << "error code:" << #NAME; \
* break;
* #define NEWLINE_
* BROTLI_DECODER_ERROR_CODES_LIST(CASE_, NEWLINE_)
* #undef CASE_
* #undef NEWLINE_
* default: LOG(FATAL) << "unknown brotli error code";
* }
* @endcode
*/
#define BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE, SEPARATOR) \
BROTLI_ERROR_CODE(_, NO_ERROR, 0) SEPARATOR \
/* Same as BrotliDecoderResult values */ \
BROTLI_ERROR_CODE(_, SUCCESS, 1) SEPARATOR \
BROTLI_ERROR_CODE(_, NEEDS_MORE_INPUT, 2) SEPARATOR \
BROTLI_ERROR_CODE(_, NEEDS_MORE_OUTPUT, 3) SEPARATOR \
\
/* Errors caused by invalid input */ \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_NIBBLE, -1) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, RESERVED, -2) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_META_NIBBLE, -3) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_ALPHABET, -4) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_SAME, -5) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, CL_SPACE, -6) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, HUFFMAN_SPACE, -7) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, CONTEXT_MAP_REPEAT, -8) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_1, -9) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_2, -10) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, TRANSFORM, -11) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, DICTIONARY, -12) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, WINDOW_BITS, -13) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_FORMAT_, DISTANCE, -16) SEPARATOR \
\
/* -17 code is reserved */ \
\
BROTLI_ERROR_CODE(_ERROR_, COMPOUND_DICTIONARY, -18) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_, DICTIONARY_NOT_SET, -19) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_, INVALID_ARGUMENTS, -20) SEPARATOR \
\
/* Memory allocation problems */ \
BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MODES, -21) SEPARATOR \
/* Literal, insert and distance trees together */ \
BROTLI_ERROR_CODE(_ERROR_ALLOC_, TREE_GROUPS, -22) SEPARATOR \
/* -23..-24 codes are reserved for distinct tree groups */ \
BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MAP, -25) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_1, -26) SEPARATOR \
BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_2, -27) SEPARATOR \
/* -28..-29 codes are reserved for dynamic ring-buffer allocation */ \
BROTLI_ERROR_CODE(_ERROR_ALLOC_, BLOCK_TYPE_TREES, -30) SEPARATOR \
\
/* "Impossible" states */ \
BROTLI_ERROR_CODE(_ERROR_, UNREACHABLE, -31)
/**
* Error code for detailed logging / production debugging.
*
* See ::BrotliDecoderGetErrorCode and ::BROTLI_LAST_ERROR_CODE.
*/
typedef enum {
#define BROTLI_COMMA_ ,
#define BROTLI_ERROR_CODE_ENUM_ITEM_(PREFIX, NAME, CODE) \
BROTLI_DECODER ## PREFIX ## NAME = CODE
BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_ENUM_ITEM_, BROTLI_COMMA_)
} BrotliDecoderErrorCode;
#undef BROTLI_ERROR_CODE_ENUM_ITEM_
#undef BROTLI_COMMA_
/**
* The value of the last error code, negative integer.
*
* All other error code values are in the range from ::BROTLI_LAST_ERROR_CODE
* to @c -1. There are also 4 other possible non-error codes @c 0 .. @c 3 in
* ::BrotliDecoderErrorCode enumeration.
*/
#define BROTLI_LAST_ERROR_CODE BROTLI_DECODER_ERROR_UNREACHABLE
/** Options to be used with ::BrotliDecoderSetParameter. */
typedef enum BrotliDecoderParameter {
/**
* Disable "canny" ring buffer allocation strategy.
*
* Ring buffer is allocated according to window size, despite the real size of
* the content.
*/
BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION = 0,
/**
* Flag that determines if "Large Window Brotli" is used.
*/
BROTLI_DECODER_PARAM_LARGE_WINDOW = 1
} BrotliDecoderParameter;
/**
* Sets the specified parameter to the given decoder instance.
*
* @param state decoder instance
* @param param parameter to set
* @param value new parameter value
* @returns ::BROTLI_FALSE if parameter is unrecognized, or value is invalid
* @returns ::BROTLI_TRUE if value is accepted
*/
BROTLI_DEC_API BROTLI_BOOL BrotliDecoderSetParameter(
BrotliDecoderState* state, BrotliDecoderParameter param, uint32_t value);
/**
* Adds LZ77 prefix dictionary, adds or replaces built-in static dictionary and
* transforms.
*
* Attached dictionary ownership is not transferred.
* Data provided to this method should be kept accessible until
* decoding is finished and decoder instance is destroyed.
*
* @note Dictionaries can NOT be attached after actual decoding is started.
*
* @param state decoder instance
* @param type dictionary data format
* @param data_size length of memory region pointed by @p data
* @param data dictionary data in format corresponding to @p type
* @returns ::BROTLI_FALSE if dictionary is corrupted,
* or dictionary count limit is reached
* @returns ::BROTLI_TRUE if dictionary is accepted / attached
*/
BROTLI_DEC_API BROTLI_BOOL BrotliDecoderAttachDictionary(
BrotliDecoderState* state, BrotliSharedDictionaryType type,
size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]);
/**
* Creates an instance of ::BrotliDecoderState and initializes it.
*
* The instance can be used once for decoding and should then be destroyed with
* ::BrotliDecoderDestroyInstance, it cannot be reused for a new decoding
* session.
*
* @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the
* case they are both zero, default memory allocators are used. @p opaque is
* passed to @p alloc_func and @p free_func when they are called. @p free_func
* has to return without doing anything when asked to free a NULL pointer.
*
* @param alloc_func custom memory allocation function
* @param free_func custom memory free function
* @param opaque custom memory manager handle
* @returns @c 0 if instance can not be allocated or initialized
* @returns pointer to initialized ::BrotliDecoderState otherwise
*/
BROTLI_DEC_API BrotliDecoderState* BrotliDecoderCreateInstance(
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
/**
* Deinitializes and frees ::BrotliDecoderState instance.
*
* @param state decoder instance to be cleaned up and deallocated
*/
BROTLI_DEC_API void BrotliDecoderDestroyInstance(BrotliDecoderState* state);
/**
* Performs one-shot memory-to-memory decompression.
*
* Decompresses the data in @p encoded_buffer into @p decoded_buffer, and sets
* @p *decoded_size to the decompressed length.
*
* @param encoded_size size of @p encoded_buffer
* @param encoded_buffer compressed data buffer with at least @p encoded_size
* addressable bytes
* @param[in, out] decoded_size @b in: size of @p decoded_buffer; \n
* @b out: length of decompressed data written to
* @p decoded_buffer
* @param decoded_buffer decompressed data destination buffer
* @returns ::BROTLI_DECODER_RESULT_ERROR if input is corrupted, memory
* allocation failed, or @p decoded_buffer is not large enough;
* @returns ::BROTLI_DECODER_RESULT_SUCCESS otherwise
*/
BROTLI_DEC_API BrotliDecoderResult BrotliDecoderDecompress(
size_t encoded_size,
const uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(encoded_size)],
size_t* decoded_size,
uint8_t decoded_buffer[BROTLI_ARRAY_PARAM(*decoded_size)]);
/**
* Decompresses the input stream to the output stream.
*
* The values @p *available_in and @p *available_out must specify the number of
* bytes addressable at @p *next_in and @p *next_out respectively.
* When @p *available_out is @c 0, @p next_out is allowed to be @c NULL.
*
* After each call, @p *available_in will be decremented by the amount of input
* bytes consumed, and the @p *next_in pointer will be incremented by that
* amount. Similarly, @p *available_out will be decremented by the amount of
* output bytes written, and the @p *next_out pointer will be incremented by
* that amount.
*
* @p total_out, if it is not a null-pointer, will be set to the number
* of bytes decompressed since the last @p state initialization.
*
* @note Input is never overconsumed, so @p next_in and @p available_in could be
* passed to the next consumer after decoding is complete.
*
* @param state decoder instance
* @param[in, out] available_in @b in: amount of available input; \n
* @b out: amount of unused input
* @param[in, out] next_in pointer to the next compressed byte
* @param[in, out] available_out @b in: length of output buffer; \n
* @b out: remaining size of output buffer
* @param[in, out] next_out output buffer cursor;
* can be @c NULL if @p available_out is @c 0
* @param[out] total_out number of bytes decompressed so far; can be @c NULL
* @returns ::BROTLI_DECODER_RESULT_ERROR if input is corrupted, memory
* allocation failed, arguments were invalid, etc.;
* use ::BrotliDecoderGetErrorCode to get detailed error code
* @returns ::BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT decoding is blocked until
* more input data is provided
* @returns ::BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT decoding is blocked until
* more output space is provided
* @returns ::BROTLI_DECODER_RESULT_SUCCESS decoding is finished, no more
* input might be consumed and no more output will be produced
*/
BROTLI_DEC_API BrotliDecoderResult BrotliDecoderDecompressStream(
BrotliDecoderState* state, size_t* available_in, const uint8_t** next_in,
size_t* available_out, uint8_t** next_out, size_t* total_out);
/**
* Checks if decoder has more output.
*
* @param state decoder instance
* @returns ::BROTLI_TRUE, if decoder has some unconsumed output
* @returns ::BROTLI_FALSE otherwise
*/
BROTLI_DEC_API BROTLI_BOOL BrotliDecoderHasMoreOutput(
const BrotliDecoderState* state);
/**
* Acquires pointer to internal output buffer.
*
* This method is used to make language bindings easier and more efficient:
* -# push data to ::BrotliDecoderDecompressStream,
* until ::BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT is reported
* -# use ::BrotliDecoderTakeOutput to peek bytes and copy to language-specific
* entity
*
* Also this could be useful if there is an output stream that is able to
* consume all the provided data (e.g. when data is saved to file system).
*
* @attention After every call to ::BrotliDecoderTakeOutput @p *size bytes of
* output are considered consumed for all consecutive calls to the
* instance methods; returned pointer becomes invalidated as well.
*
* @note Decoder output is not guaranteed to be contiguous. This means that
* after the size-unrestricted call to ::BrotliDecoderTakeOutput,
* immediate next call to ::BrotliDecoderTakeOutput may return more data.
*
* @param state decoder instance
* @param[in, out] size @b in: number of bytes caller is ready to take, @c 0 if
* any amount could be handled; \n
* @b out: amount of data pointed by returned pointer and
* considered consumed; \n
* out value is never greater than in value, unless it is @c 0
* @returns pointer to output data
*/
BROTLI_DEC_API const uint8_t* BrotliDecoderTakeOutput(
BrotliDecoderState* state, size_t* size);
/**
* Checks if instance has already consumed input.
*
* Instance that returns ::BROTLI_FALSE is considered "fresh" and could be
* reused.
*
* @param state decoder instance
* @returns ::BROTLI_TRUE if decoder has already used some input bytes
* @returns ::BROTLI_FALSE otherwise
*/
BROTLI_DEC_API BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* state);
/**
* Checks if decoder instance reached the final state.
*
* @param state decoder instance
* @returns ::BROTLI_TRUE if decoder is in a state where it reached the end of
* the input and produced all of the output
* @returns ::BROTLI_FALSE otherwise
*/
BROTLI_DEC_API BROTLI_BOOL BrotliDecoderIsFinished(
const BrotliDecoderState* state);
/**
* Acquires a detailed error code.
*
* Should be used only after ::BrotliDecoderDecompressStream returns
* ::BROTLI_DECODER_RESULT_ERROR.
*
* See also ::BrotliDecoderErrorString
*
* @param state decoder instance
* @returns last saved error code
*/
BROTLI_DEC_API BrotliDecoderErrorCode BrotliDecoderGetErrorCode(
const BrotliDecoderState* state);
/**
* Converts error code to a c-string.
*/
BROTLI_DEC_API const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c);
/**
* Gets a decoder library version.
*
* Look at BROTLI_VERSION for more information.
*/
BROTLI_DEC_API uint32_t BrotliDecoderVersion(void);
/**
* Callback to fire on metadata block start.
*
* After this callback is fired, if @p size is not @c 0, it is followed by
* ::brotli_decoder_metadata_chunk_func as more metadata block contents become
* accessible.
*
* @param opaque callback handle
* @param size size of metadata block
*/
typedef void (*brotli_decoder_metadata_start_func)(void* opaque, size_t size);
/**
* Callback to fire on metadata block chunk becomes available.
*
* This function can be invoked multiple times per metadata block; block should
* be considered finished when sum of @p size matches the announced metadata
* block size. Chunks contents pointed by @p data are transient and shouln not
* be accessed after leaving the callback.
*
* @param opaque callback handle
* @param data pointer to metadata contents
* @param size size of metadata block chunk, at least @c 1
*/
typedef void (*brotli_decoder_metadata_chunk_func)(void* opaque,
const uint8_t* data,
size_t size);
/**
* Sets callback for receiving metadata blocks.
*
* @param state decoder instance
* @param start_func callback on metadata block start
* @param chunk_func callback on metadata block chunk
* @param opaque callback handle
*/
BROTLI_DEC_API void BrotliDecoderSetMetadataCallbacks(
BrotliDecoderState* state,
brotli_decoder_metadata_start_func start_func,
brotli_decoder_metadata_chunk_func chunk_func, void* opaque);
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_DEC_DECODE_H_ */

View File

@ -1,501 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/**
* @file
* API for Brotli compression.
*/
#ifndef BROTLI_ENC_ENCODE_H_
#define BROTLI_ENC_ENCODE_H_
#include <brotli/port.h>
#include <brotli/shared_dictionary.h>
#include <brotli/types.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
/** Minimal value for ::BROTLI_PARAM_LGWIN parameter. */
#define BROTLI_MIN_WINDOW_BITS 10
/**
* Maximal value for ::BROTLI_PARAM_LGWIN parameter.
*
* @note equal to @c BROTLI_MAX_DISTANCE_BITS constant.
*/
#define BROTLI_MAX_WINDOW_BITS 24
/**
* Maximal value for ::BROTLI_PARAM_LGWIN parameter
* in "Large Window Brotli" (32-bit).
*/
#define BROTLI_LARGE_MAX_WINDOW_BITS 30
/** Minimal value for ::BROTLI_PARAM_LGBLOCK parameter. */
#define BROTLI_MIN_INPUT_BLOCK_BITS 16
/** Maximal value for ::BROTLI_PARAM_LGBLOCK parameter. */
#define BROTLI_MAX_INPUT_BLOCK_BITS 24
/** Minimal value for ::BROTLI_PARAM_QUALITY parameter. */
#define BROTLI_MIN_QUALITY 0
/** Maximal value for ::BROTLI_PARAM_QUALITY parameter. */
#define BROTLI_MAX_QUALITY 11
/** Options for ::BROTLI_PARAM_MODE parameter. */
typedef enum BrotliEncoderMode {
/**
* Default compression mode.
*
* In this mode compressor does not know anything in advance about the
* properties of the input.
*/
BROTLI_MODE_GENERIC = 0,
/** Compression mode for UTF-8 formatted text input. */
BROTLI_MODE_TEXT = 1,
/** Compression mode used in WOFF 2.0. */
BROTLI_MODE_FONT = 2
} BrotliEncoderMode;
/** Default value for ::BROTLI_PARAM_QUALITY parameter. */
#define BROTLI_DEFAULT_QUALITY 11
/** Default value for ::BROTLI_PARAM_LGWIN parameter. */
#define BROTLI_DEFAULT_WINDOW 22
/** Default value for ::BROTLI_PARAM_MODE parameter. */
#define BROTLI_DEFAULT_MODE BROTLI_MODE_GENERIC
/** Operations that can be performed by streaming encoder. */
typedef enum BrotliEncoderOperation {
/**
* Process input.
*
* Encoder may postpone producing output, until it has processed enough input.
*/
BROTLI_OPERATION_PROCESS = 0,
/**
* Produce output for all processed input.
*
* Actual flush is performed when input stream is depleted and there is enough
* space in output stream. This means that client should repeat
* ::BROTLI_OPERATION_FLUSH operation until @p available_in becomes @c 0, and
* ::BrotliEncoderHasMoreOutput returns ::BROTLI_FALSE. If output is acquired
* via ::BrotliEncoderTakeOutput, then operation should be repeated after
* output buffer is drained.
*
* @warning Until flush is complete, client @b SHOULD @b NOT swap,
* reduce or extend input stream.
*
* When flush is complete, output data will be sufficient for decoder to
* reproduce all the given input.
*/
BROTLI_OPERATION_FLUSH = 1,
/**
* Finalize the stream.
*
* Actual finalization is performed when input stream is depleted and there is
* enough space in output stream. This means that client should repeat
* ::BROTLI_OPERATION_FINISH operation until @p available_in becomes @c 0, and
* ::BrotliEncoderHasMoreOutput returns ::BROTLI_FALSE. If output is acquired
* via ::BrotliEncoderTakeOutput, then operation should be repeated after
* output buffer is drained.
*
* @warning Until finalization is complete, client @b SHOULD @b NOT swap,
* reduce or extend input stream.
*
* Helper function ::BrotliEncoderIsFinished checks if stream is finalized and
* output fully dumped.
*
* Adding more input data to finalized stream is impossible.
*/
BROTLI_OPERATION_FINISH = 2,
/**
* Emit metadata block to stream.
*
* Metadata is opaque to Brotli: neither encoder, nor decoder processes this
* data or relies on it. It may be used to pass some extra information from
* encoder client to decoder client without interfering with main data stream.
*
* @note Encoder may emit empty metadata blocks internally, to pad encoded
* stream to byte boundary.
*
* @warning Until emitting metadata is complete client @b SHOULD @b NOT swap,
* reduce or extend input stream.
*
* @warning The whole content of input buffer is considered to be the content
* of metadata block. Do @b NOT @e append metadata to input stream,
* before it is depleted with other operations.
*
* Stream is soft-flushed before metadata block is emitted. Metadata block
* @b MUST be no longer than than 16MiB.
*/
BROTLI_OPERATION_EMIT_METADATA = 3
} BrotliEncoderOperation;
/** Options to be used with ::BrotliEncoderSetParameter. */
typedef enum BrotliEncoderParameter {
/**
* Tune encoder for specific input.
*
* ::BrotliEncoderMode enumerates all available values.
*/
BROTLI_PARAM_MODE = 0,
/**
* The main compression speed-density lever.
*
* The higher the quality, the slower the compression. Range is
* from ::BROTLI_MIN_QUALITY to ::BROTLI_MAX_QUALITY.
*/
BROTLI_PARAM_QUALITY = 1,
/**
* Recommended sliding LZ77 window size.
*
* Encoder may reduce this value, e.g. if input is much smaller than
* window size.
*
* Window size is `(1 << value) - 16`.
*
* Range is from ::BROTLI_MIN_WINDOW_BITS to ::BROTLI_MAX_WINDOW_BITS.
*/
BROTLI_PARAM_LGWIN = 2,
/**
* Recommended input block size.
*
* Encoder may reduce this value, e.g. if input is much smaller than input
* block size.
*
* Range is from ::BROTLI_MIN_INPUT_BLOCK_BITS to
* ::BROTLI_MAX_INPUT_BLOCK_BITS.
*
* @note Bigger input block size allows better compression, but consumes more
* memory. \n The rough formula of memory used for temporary input
* storage is `3 << lgBlock`.
*/
BROTLI_PARAM_LGBLOCK = 3,
/**
* Flag that affects usage of "literal context modeling" format feature.
*
* This flag is a "decoding-speed vs compression ratio" trade-off.
*/
BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING = 4,
/**
* Estimated total input size for all ::BrotliEncoderCompressStream calls.
*
* The default value is 0, which means that the total input size is unknown.
*/
BROTLI_PARAM_SIZE_HINT = 5,
/**
* Flag that determines if "Large Window Brotli" is used.
*/
BROTLI_PARAM_LARGE_WINDOW = 6,
/**
* Recommended number of postfix bits (NPOSTFIX).
*
* Encoder may change this value.
*
* Range is from 0 to ::BROTLI_MAX_NPOSTFIX.
*/
BROTLI_PARAM_NPOSTFIX = 7,
/**
* Recommended number of direct distance codes (NDIRECT).
*
* Encoder may change this value.
*
* Range is from 0 to (15 << NPOSTFIX) in steps of (1 << NPOSTFIX).
*/
BROTLI_PARAM_NDIRECT = 8,
/**
* Number of bytes of input stream already processed by a different instance.
*
* @note It is important to configure all the encoder instances with same
* parameters (except this one) in order to allow all the encoded parts
* obey the same restrictions implied by header.
*
* If offset is not 0, then stream header is omitted.
* In any case output start is byte aligned, so for proper streams stitching
* "predecessor" stream must be flushed.
*
* Range is not artificially limited, but all the values greater or equal to
* maximal window size have the same effect. Values greater than 2**30 are not
* allowed.
*/
BROTLI_PARAM_STREAM_OFFSET = 9
} BrotliEncoderParameter;
/**
* Opaque structure that holds encoder state.
*
* Allocated and initialized with ::BrotliEncoderCreateInstance.
* Cleaned up and deallocated with ::BrotliEncoderDestroyInstance.
*/
typedef struct BrotliEncoderStateStruct BrotliEncoderState;
/**
* Sets the specified parameter to the given encoder instance.
*
* @param state encoder instance
* @param param parameter to set
* @param value new parameter value
* @returns ::BROTLI_FALSE if parameter is unrecognized, or value is invalid
* @returns ::BROTLI_FALSE if value of parameter can not be changed at current
* encoder state (e.g. when encoding is started, window size might be
* already encoded and therefore it is impossible to change it)
* @returns ::BROTLI_TRUE if value is accepted
* @warning invalid values might be accepted in case they would not break
* encoding process.
*/
BROTLI_ENC_API BROTLI_BOOL BrotliEncoderSetParameter(
BrotliEncoderState* state, BrotliEncoderParameter param, uint32_t value);
/**
* Creates an instance of ::BrotliEncoderState and initializes it.
*
* @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the
* case they are both zero, default memory allocators are used. @p opaque is
* passed to @p alloc_func and @p free_func when they are called. @p free_func
* has to return without doing anything when asked to free a NULL pointer.
*
* @param alloc_func custom memory allocation function
* @param free_func custom memory free function
* @param opaque custom memory manager handle
* @returns @c 0 if instance can not be allocated or initialized
* @returns pointer to initialized ::BrotliEncoderState otherwise
*/
BROTLI_ENC_API BrotliEncoderState* BrotliEncoderCreateInstance(
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
/**
* Deinitializes and frees ::BrotliEncoderState instance.
*
* @param state decoder instance to be cleaned up and deallocated
*/
BROTLI_ENC_API void BrotliEncoderDestroyInstance(BrotliEncoderState* state);
/* Opaque type for pointer to different possible internal structures containing
dictionary prepared for the encoder */
typedef struct BrotliEncoderPreparedDictionaryStruct
BrotliEncoderPreparedDictionary;
/**
* Prepares a shared dictionary from the given file format for the encoder.
*
* @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the
* case they are both zero, default memory allocators are used. @p opaque is
* passed to @p alloc_func and @p free_func when they are called. @p free_func
* has to return without doing anything when asked to free a NULL pointer.
*
* @param type type of dictionary stored in data
* @param data_size size of @p data buffer
* @param data pointer to the dictionary data
* @param quality the maximum Brotli quality to prepare the dictionary for,
* use BROTLI_MAX_QUALITY by default
* @param alloc_func custom memory allocation function
* @param free_func custom memory free function
* @param opaque custom memory manager handle
*/
BROTLI_ENC_API BrotliEncoderPreparedDictionary*
BrotliEncoderPrepareDictionary(BrotliSharedDictionaryType type,
size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)],
int quality,
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
BROTLI_ENC_API void BrotliEncoderDestroyPreparedDictionary(
BrotliEncoderPreparedDictionary* dictionary);
/**
* Attaches a prepared dictionary of any type to the encoder. Can be used
* multiple times to attach multiple dictionaries. The dictionary type was
* determined by BrotliEncoderPrepareDictionary. Multiple raw prefix
* dictionaries and/or max 1 serialized dictionary with custom words can be
* attached.
*
* @returns ::BROTLI_FALSE in case of error
* @returns ::BROTLI_TRUE otherwise
*/
BROTLI_ENC_API BROTLI_BOOL BrotliEncoderAttachPreparedDictionary(
BrotliEncoderState* state,
const BrotliEncoderPreparedDictionary* dictionary);
/**
* Calculates the output size bound for the given @p input_size.
*
* @warning Result is only valid if quality is at least @c 2 and, in
* case ::BrotliEncoderCompressStream was used, no flushes
* (::BROTLI_OPERATION_FLUSH) were performed.
*
* @param input_size size of projected input
* @returns @c 0 if result does not fit @c size_t
*/
BROTLI_ENC_API size_t BrotliEncoderMaxCompressedSize(size_t input_size);
/**
* Performs one-shot memory-to-memory compression.
*
* Compresses the data in @p input_buffer into @p encoded_buffer, and sets
* @p *encoded_size to the compressed length.
*
* @note If ::BrotliEncoderMaxCompressedSize(@p input_size) returns non-zero
* value, then output is guaranteed to be no longer than that.
*
* @note If @p lgwin is greater than ::BROTLI_MAX_WINDOW_BITS then resulting
* stream might be incompatible with RFC 7932; to decode such streams,
* decoder should be configured with
* ::BROTLI_DECODER_PARAM_LARGE_WINDOW = @c 1
*
* @param quality quality parameter value, e.g. ::BROTLI_DEFAULT_QUALITY
* @param lgwin lgwin parameter value, e.g. ::BROTLI_DEFAULT_WINDOW
* @param mode mode parameter value, e.g. ::BROTLI_DEFAULT_MODE
* @param input_size size of @p input_buffer
* @param input_buffer input data buffer with at least @p input_size
* addressable bytes
* @param[in, out] encoded_size @b in: size of @p encoded_buffer; \n
* @b out: length of compressed data written to
* @p encoded_buffer, or @c 0 if compression fails
* @param encoded_buffer compressed data destination buffer
* @returns ::BROTLI_FALSE in case of compression error
* @returns ::BROTLI_FALSE if output buffer is too small
* @returns ::BROTLI_TRUE otherwise
*/
BROTLI_ENC_API BROTLI_BOOL BrotliEncoderCompress(
int quality, int lgwin, BrotliEncoderMode mode, size_t input_size,
const uint8_t input_buffer[BROTLI_ARRAY_PARAM(input_size)],
size_t* encoded_size,
uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(*encoded_size)]);
/**
* Compresses input stream to output stream.
*
* The values @p *available_in and @p *available_out must specify the number of
* bytes addressable at @p *next_in and @p *next_out respectively.
* When @p *available_out is @c 0, @p next_out is allowed to be @c NULL.
*
* After each call, @p *available_in will be decremented by the amount of input
* bytes consumed, and the @p *next_in pointer will be incremented by that
* amount. Similarly, @p *available_out will be decremented by the amount of
* output bytes written, and the @p *next_out pointer will be incremented by
* that amount.
*
* @p total_out, if it is not a null-pointer, will be set to the number
* of bytes compressed since the last @p state initialization.
*
*
*
* Internally workflow consists of 3 tasks:
* -# (optionally) copy input data to internal buffer
* -# actually compress data and (optionally) store it to internal buffer
* -# (optionally) copy compressed bytes from internal buffer to output stream
*
* Whenever all 3 tasks can't move forward anymore, or error occurs, this
* method returns the control flow to caller.
*
* @p op is used to perform flush, finish the stream, or inject metadata block.
* See ::BrotliEncoderOperation for more information.
*
* Flushing the stream means forcing encoding of all input passed to encoder and
* completing the current output block, so it could be fully decoded by stream
* decoder. To perform flush set @p op to ::BROTLI_OPERATION_FLUSH.
* Under some circumstances (e.g. lack of output stream capacity) this operation
* would require several calls to ::BrotliEncoderCompressStream. The method must
* be called again until both input stream is depleted and encoder has no more
* output (see ::BrotliEncoderHasMoreOutput) after the method is called.
*
* Finishing the stream means encoding of all input passed to encoder and
* adding specific "final" marks, so stream decoder could determine that stream
* is complete. To perform finish set @p op to ::BROTLI_OPERATION_FINISH.
* Under some circumstances (e.g. lack of output stream capacity) this operation
* would require several calls to ::BrotliEncoderCompressStream. The method must
* be called again until both input stream is depleted and encoder has no more
* output (see ::BrotliEncoderHasMoreOutput) after the method is called.
*
* @warning When flushing and finishing, @p op should not change until operation
* is complete; input stream should not be swapped, reduced or
* extended as well.
*
* @param state encoder instance
* @param op requested operation
* @param[in, out] available_in @b in: amount of available input; \n
* @b out: amount of unused input
* @param[in, out] next_in pointer to the next input byte
* @param[in, out] available_out @b in: length of output buffer; \n
* @b out: remaining size of output buffer
* @param[in, out] next_out compressed output buffer cursor;
* can be @c NULL if @p available_out is @c 0
* @param[out] total_out number of bytes produced so far; can be @c NULL
* @returns ::BROTLI_FALSE if there was an error
* @returns ::BROTLI_TRUE otherwise
*/
BROTLI_ENC_API BROTLI_BOOL BrotliEncoderCompressStream(
BrotliEncoderState* state, BrotliEncoderOperation op, size_t* available_in,
const uint8_t** next_in, size_t* available_out, uint8_t** next_out,
size_t* total_out);
/**
* Checks if encoder instance reached the final state.
*
* @param state encoder instance
* @returns ::BROTLI_TRUE if encoder is in a state where it reached the end of
* the input and produced all of the output
* @returns ::BROTLI_FALSE otherwise
*/
BROTLI_ENC_API BROTLI_BOOL BrotliEncoderIsFinished(BrotliEncoderState* state);
/**
* Checks if encoder has more output.
*
* @param state encoder instance
* @returns ::BROTLI_TRUE, if encoder has some unconsumed output
* @returns ::BROTLI_FALSE otherwise
*/
BROTLI_ENC_API BROTLI_BOOL BrotliEncoderHasMoreOutput(
BrotliEncoderState* state);
/**
* Acquires pointer to internal output buffer.
*
* This method is used to make language bindings easier and more efficient:
* -# push data to ::BrotliEncoderCompressStream,
* until ::BrotliEncoderHasMoreOutput returns BROTLI_TRUE
* -# use ::BrotliEncoderTakeOutput to peek bytes and copy to language-specific
* entity
*
* Also this could be useful if there is an output stream that is able to
* consume all the provided data (e.g. when data is saved to file system).
*
* @attention After every call to ::BrotliEncoderTakeOutput @p *size bytes of
* output are considered consumed for all consecutive calls to the
* instance methods; returned pointer becomes invalidated as well.
*
* @note Encoder output is not guaranteed to be contiguous. This means that
* after the size-unrestricted call to ::BrotliEncoderTakeOutput,
* immediate next call to ::BrotliEncoderTakeOutput may return more data.
*
* @param state encoder instance
* @param[in, out] size @b in: number of bytes caller is ready to take, @c 0 if
* any amount could be handled; \n
* @b out: amount of data pointed by returned pointer and
* considered consumed; \n
* out value is never greater than in value, unless it is @c 0
* @returns pointer to output data
*/
BROTLI_ENC_API const uint8_t* BrotliEncoderTakeOutput(
BrotliEncoderState* state, size_t* size);
/* Returns the estimated peak memory usage (in bytes) of the BrotliCompress()
function, not counting the memory needed for the input and output. */
BROTLI_ENC_EXTRA_API size_t BrotliEncoderEstimatePeakMemoryUsage(
int quality, int lgwin, size_t input_size);
/* Returns 0 if dictionary is not valid; otherwise returns allocation size. */
BROTLI_ENC_EXTRA_API size_t BrotliEncoderGetPreparedDictionarySize(
const BrotliEncoderPreparedDictionary* dictionary);
/**
* Gets an encoder library version.
*
* Look at BROTLI_VERSION for more information.
*/
BROTLI_ENC_API uint32_t BrotliEncoderVersion(void);
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_ENC_ENCODE_H_ */

View File

@ -1,305 +0,0 @@
/* Copyright 2016 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Macros for compiler / platform specific API declarations. */
#ifndef BROTLI_COMMON_PORT_H_
#define BROTLI_COMMON_PORT_H_
/* The following macros were borrowed from https://github.com/nemequ/hedley
* with permission of original author - Evan Nemerson <evan@nemerson.com> */
/* >>> >>> >>> hedley macros */
#define BROTLI_MAKE_VERSION(major, minor, revision) \
(((major) * 1000000) + ((minor) * 1000) + (revision))
#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
#define BROTLI_GNUC_VERSION \
BROTLI_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#elif defined(__GNUC__)
#define BROTLI_GNUC_VERSION BROTLI_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, 0)
#endif
#if defined(BROTLI_GNUC_VERSION)
#define BROTLI_GNUC_VERSION_CHECK(major, minor, patch) \
(BROTLI_GNUC_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
#else
#define BROTLI_GNUC_VERSION_CHECK(major, minor, patch) (0)
#endif
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
#define BROTLI_MSVC_VERSION \
BROTLI_MAKE_VERSION((_MSC_FULL_VER / 10000000), \
(_MSC_FULL_VER % 10000000) / 100000, \
(_MSC_FULL_VER % 100000) / 100)
#elif defined(_MSC_FULL_VER)
#define BROTLI_MSVC_VERSION \
BROTLI_MAKE_VERSION((_MSC_FULL_VER / 1000000), \
(_MSC_FULL_VER % 1000000) / 10000, \
(_MSC_FULL_VER % 10000) / 10)
#elif defined(_MSC_VER)
#define BROTLI_MSVC_VERSION \
BROTLI_MAKE_VERSION(_MSC_VER / 100, _MSC_VER % 100, 0)
#endif
#if !defined(_MSC_VER)
#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) (0)
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) \
(_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) \
(_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
#else
#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) \
(_MSC_VER >= ((major * 100) + (minor)))
#endif
#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
#define BROTLI_INTEL_VERSION \
BROTLI_MAKE_VERSION(__INTEL_COMPILER / 100, \
__INTEL_COMPILER % 100, \
__INTEL_COMPILER_UPDATE)
#elif defined(__INTEL_COMPILER)
#define BROTLI_INTEL_VERSION \
BROTLI_MAKE_VERSION(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
#endif
#if defined(BROTLI_INTEL_VERSION)
#define BROTLI_INTEL_VERSION_CHECK(major, minor, patch) \
(BROTLI_INTEL_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
#else
#define BROTLI_INTEL_VERSION_CHECK(major, minor, patch) (0)
#endif
#if defined(__PGI) && \
defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
#define BROTLI_PGI_VERSION \
BROTLI_MAKE_VERSION(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
#endif
#if defined(BROTLI_PGI_VERSION)
#define BROTLI_PGI_VERSION_CHECK(major, minor, patch) \
(BROTLI_PGI_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
#else
#define BROTLI_PGI_VERSION_CHECK(major, minor, patch) (0)
#endif
#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
#define BROTLI_SUNPRO_VERSION \
BROTLI_MAKE_VERSION( \
(((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), \
(((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), \
(__SUNPRO_C & 0xf) * 10)
#elif defined(__SUNPRO_C)
#define BROTLI_SUNPRO_VERSION \
BROTLI_MAKE_VERSION((__SUNPRO_C >> 8) & 0xf, \
(__SUNPRO_C >> 4) & 0xf, \
(__SUNPRO_C) & 0xf)
#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
#define BROTLI_SUNPRO_VERSION \
BROTLI_MAKE_VERSION( \
(((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), \
(((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), \
(__SUNPRO_CC & 0xf) * 10)
#elif defined(__SUNPRO_CC)
#define BROTLI_SUNPRO_VERSION \
BROTLI_MAKE_VERSION((__SUNPRO_CC >> 8) & 0xf, \
(__SUNPRO_CC >> 4) & 0xf, \
(__SUNPRO_CC) & 0xf)
#endif
#if defined(BROTLI_SUNPRO_VERSION)
#define BROTLI_SUNPRO_VERSION_CHECK(major, minor, patch) \
(BROTLI_SUNPRO_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
#else
#define BROTLI_SUNPRO_VERSION_CHECK(major, minor, patch) (0)
#endif
#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
#define BROTLI_ARM_VERSION \
BROTLI_MAKE_VERSION((__ARMCOMPILER_VERSION / 1000000), \
(__ARMCOMPILER_VERSION % 1000000) / 10000, \
(__ARMCOMPILER_VERSION % 10000) / 100)
#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
#define BROTLI_ARM_VERSION \
BROTLI_MAKE_VERSION((__ARMCC_VERSION / 1000000), \
(__ARMCC_VERSION % 1000000) / 10000, \
(__ARMCC_VERSION % 10000) / 100)
#endif
#if defined(BROTLI_ARM_VERSION)
#define BROTLI_ARM_VERSION_CHECK(major, minor, patch) \
(BROTLI_ARM_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
#else
#define BROTLI_ARM_VERSION_CHECK(major, minor, patch) (0)
#endif
#if defined(__ibmxl__)
#define BROTLI_IBM_VERSION \
BROTLI_MAKE_VERSION(__ibmxl_version__, \
__ibmxl_release__, \
__ibmxl_modification__)
#elif defined(__xlC__) && defined(__xlC_ver__)
#define BROTLI_IBM_VERSION \
BROTLI_MAKE_VERSION(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
#elif defined(__xlC__)
#define BROTLI_IBM_VERSION BROTLI_MAKE_VERSION(__xlC__ >> 8, __xlC__ & 0xff, 0)
#endif
#if defined(BROTLI_IBM_VERSION)
#define BROTLI_IBM_VERSION_CHECK(major, minor, patch) \
(BROTLI_IBM_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
#else
#define BROTLI_IBM_VERSION_CHECK(major, minor, patch) (0)
#endif
#if defined(__TI_COMPILER_VERSION__)
#define BROTLI_TI_VERSION \
BROTLI_MAKE_VERSION((__TI_COMPILER_VERSION__ / 1000000), \
(__TI_COMPILER_VERSION__ % 1000000) / 1000, \
(__TI_COMPILER_VERSION__ % 1000))
#endif
#if defined(BROTLI_TI_VERSION)
#define BROTLI_TI_VERSION_CHECK(major, minor, patch) \
(BROTLI_TI_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
#else
#define BROTLI_TI_VERSION_CHECK(major, minor, patch) (0)
#endif
#if defined(__IAR_SYSTEMS_ICC__)
#if __VER__ > 1000
#define BROTLI_IAR_VERSION \
BROTLI_MAKE_VERSION((__VER__ / 1000000), \
(__VER__ / 1000) % 1000, \
(__VER__ % 1000))
#else
#define BROTLI_IAR_VERSION BROTLI_MAKE_VERSION(VER / 100, __VER__ % 100, 0)
#endif
#endif
#if defined(BROTLI_IAR_VERSION)
#define BROTLI_IAR_VERSION_CHECK(major, minor, patch) \
(BROTLI_IAR_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
#else
#define BROTLI_IAR_VERSION_CHECK(major, minor, patch) (0)
#endif
#if defined(__TINYC__)
#define BROTLI_TINYC_VERSION \
BROTLI_MAKE_VERSION(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
#endif
#if defined(BROTLI_TINYC_VERSION)
#define BROTLI_TINYC_VERSION_CHECK(major, minor, patch) \
(BROTLI_TINYC_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
#else
#define BROTLI_TINYC_VERSION_CHECK(major, minor, patch) (0)
#endif
#if defined(__has_attribute)
#define BROTLI_GNUC_HAS_ATTRIBUTE(attribute, major, minor, patch) \
__has_attribute(attribute)
#else
#define BROTLI_GNUC_HAS_ATTRIBUTE(attribute, major, minor, patch) \
BROTLI_GNUC_VERSION_CHECK(major, minor, patch)
#endif
#if defined(__has_builtin)
#define BROTLI_GNUC_HAS_BUILTIN(builtin, major, minor, patch) \
__has_builtin(builtin)
#else
#define BROTLI_GNUC_HAS_BUILTIN(builtin, major, minor, patch) \
BROTLI_GNUC_VERSION_CHECK(major, minor, patch)
#endif
#if defined(__has_feature)
#define BROTLI_HAS_FEATURE(feature) __has_feature(feature)
#else
#define BROTLI_HAS_FEATURE(feature) (0)
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
#define BROTLI_PUBLIC
#elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) || \
BROTLI_TI_VERSION_CHECK(8, 0, 0) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
BROTLI_IBM_VERSION_CHECK(13, 1, 0) || \
BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \
(BROTLI_TI_VERSION_CHECK(7, 3, 0) && \
defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__))
#define BROTLI_PUBLIC __attribute__ ((visibility ("default")))
#else
#define BROTLI_PUBLIC
#endif
/* BROTLI_INTERNAL could be defined to override visibility, e.g. for tests. */
#if !defined(BROTLI_INTERNAL)
#if defined(_WIN32) || defined(__CYGWIN__)
#define BROTLI_INTERNAL
#elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) || \
BROTLI_TI_VERSION_CHECK(8, 0, 0) || \
BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
BROTLI_IBM_VERSION_CHECK(13, 1, 0) || \
BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \
(BROTLI_TI_VERSION_CHECK(7, 3, 0) && \
defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__))
#define BROTLI_INTERNAL __attribute__ ((visibility ("hidden")))
#else
#define BROTLI_INTERNAL
#endif
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(__STDC_NO_VLA__) && !defined(__cplusplus) && \
!defined(__PGI) && !defined(__PGIC__) && !defined(__TINYC__) && \
!defined(__clang__)
#define BROTLI_ARRAY_PARAM(name) (name)
#else
#define BROTLI_ARRAY_PARAM(name)
#endif
/* <<< <<< <<< end of hedley macros. */
#if defined(BROTLI_SHARED_COMPILATION)
#if defined(_WIN32)
#if defined(BROTLICOMMON_SHARED_COMPILATION)
#define BROTLI_COMMON_API __declspec(dllexport)
#else
#define BROTLI_COMMON_API __declspec(dllimport)
#endif /* BROTLICOMMON_SHARED_COMPILATION */
#if defined(BROTLIDEC_SHARED_COMPILATION)
#define BROTLI_DEC_API __declspec(dllexport)
#else
#define BROTLI_DEC_API __declspec(dllimport)
#endif /* BROTLIDEC_SHARED_COMPILATION */
#if defined(BROTLIENC_SHARED_COMPILATION)
#define BROTLI_ENC_API __declspec(dllexport)
#else
#define BROTLI_ENC_API __declspec(dllimport)
#endif /* BROTLIENC_SHARED_COMPILATION */
#else /* _WIN32 */
#define BROTLI_COMMON_API BROTLI_PUBLIC
#define BROTLI_DEC_API BROTLI_PUBLIC
#define BROTLI_ENC_API BROTLI_PUBLIC
#endif /* _WIN32 */
#else /* BROTLI_SHARED_COMPILATION */
#define BROTLI_COMMON_API
#define BROTLI_DEC_API
#define BROTLI_ENC_API
#endif
#if defined(BROTLI_BUILD_ENC_EXTRA_API)
#define BROTLI_ENC_EXTRA_API BROTLI_ENC_API
#else
#define BROTLI_ENC_EXTRA_API BROTLI_INTERNAL
#endif
#endif /* BROTLI_COMMON_PORT_H_ */

View File

@ -1,97 +0,0 @@
/* Copyright 2017 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* (Opaque) Shared Dictionary definition and utilities. */
#ifndef BROTLI_COMMON_SHARED_DICTIONARY_H_
#define BROTLI_COMMON_SHARED_DICTIONARY_H_
#include <brotli/port.h>
#include <brotli/types.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#define SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH 4
#define SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH 31
#define SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS 64
#define SHARED_BROTLI_MAX_COMPOUND_DICTS 15
/**
* Opaque structure that holds shared dictionary data.
*
* Allocated and initialized with ::BrotliSharedDictionaryCreateInstance.
* Cleaned up and deallocated with ::BrotliSharedDictionaryDestroyInstance.
*/
typedef struct BrotliSharedDictionaryStruct BrotliSharedDictionary;
/**
* Input data type for ::BrotliSharedDictionaryAttach.
*/
typedef enum BrotliSharedDictionaryType {
/** Raw LZ77 prefix dictionary. */
BROTLI_SHARED_DICTIONARY_RAW = 0,
/** Serialized shared dictionary. */
BROTLI_SHARED_DICTIONARY_SERIALIZED = 1
} BrotliSharedDictionaryType;
/**
* Creates an instance of ::BrotliSharedDictionary.
*
* Fresh instance has default word dictionary and transforms
* and no LZ77 prefix dictionary.
*
* @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the
* case they are both zero, default memory allocators are used. @p opaque is
* passed to @p alloc_func and @p free_func when they are called. @p free_func
* has to return without doing anything when asked to free a NULL pointer.
*
* @param alloc_func custom memory allocation function
* @param free_func custom memory free function
* @param opaque custom memory manager handle
* @returns @c 0 if instance can not be allocated or initialized
* @returns pointer to initialized ::BrotliSharedDictionary otherwise
*/
BROTLI_COMMON_API BrotliSharedDictionary* BrotliSharedDictionaryCreateInstance(
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
/**
* Deinitializes and frees ::BrotliSharedDictionary instance.
*
* @param dict shared dictionary instance to be cleaned up and deallocated
*/
BROTLI_COMMON_API void BrotliSharedDictionaryDestroyInstance(
BrotliSharedDictionary* dict);
/**
* Attaches dictionary to a given instance of ::BrotliSharedDictionary.
*
* Dictionary to be attached is represented in a serialized format as a region
* of memory.
*
* Provided data it partially referenced by a resulting (compound) dictionary,
* and should be kept untouched, while at least one compound dictionary uses it.
* This way memory overhead is kept minimal by the cost of additional resource
* management.
*
* @param dict dictionary to extend
* @param type type of dictionary to attach
* @param data_size size of @p data
* @param data serialized dictionary of type @p type, with at least @p data_size
* addressable bytes
* @returns ::BROTLI_TRUE if provided dictionary is successfully attached
* @returns ::BROTLI_FALSE otherwise
*/
BROTLI_COMMON_API BROTLI_BOOL BrotliSharedDictionaryAttach(
BrotliSharedDictionary* dict, BrotliSharedDictionaryType type,
size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]);
#if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */
#endif
#endif /* BROTLI_COMMON_SHARED_DICTIONARY_H_ */

View File

@ -1,83 +0,0 @@
/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/**
* @file
* Common types used in decoder and encoder API.
*/
#ifndef BROTLI_COMMON_TYPES_H_
#define BROTLI_COMMON_TYPES_H_
#include <stddef.h> /* for size_t */
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef __int64 int64_t;
#else
#include <stdint.h>
#endif /* defined(_MSC_VER) && (_MSC_VER < 1600) */
/**
* A portable @c bool replacement.
*
* ::BROTLI_BOOL is a "documentation" type: actually it is @c int, but in API it
* denotes a type, whose only values are ::BROTLI_TRUE and ::BROTLI_FALSE.
*
* ::BROTLI_BOOL values passed to Brotli should either be ::BROTLI_TRUE or
* ::BROTLI_FALSE, or be a result of ::TO_BROTLI_BOOL macros.
*
* ::BROTLI_BOOL values returned by Brotli should not be tested for equality
* with @c true, @c false, ::BROTLI_TRUE, ::BROTLI_FALSE, but rather should be
* evaluated, for example: @code{.cpp}
* if (SomeBrotliFunction(encoder, BROTLI_TRUE) &&
* !OtherBrotliFunction(decoder, BROTLI_FALSE)) {
* bool x = !!YetAnotherBrotliFunction(encoder, TO_BROLTI_BOOL(2 * 2 == 4));
* DoSomething(x);
* }
* @endcode
*/
#define BROTLI_BOOL int
/** Portable @c true replacement. */
#define BROTLI_TRUE 1
/** Portable @c false replacement. */
#define BROTLI_FALSE 0
/** @c bool to ::BROTLI_BOOL conversion macros. */
#define TO_BROTLI_BOOL(X) (!!(X) ? BROTLI_TRUE : BROTLI_FALSE)
#define BROTLI_MAKE_UINT64_T(high, low) ((((uint64_t)(high)) << 32) | low)
#define BROTLI_UINT32_MAX (~((uint32_t)0))
#define BROTLI_SIZE_MAX (~((size_t)0))
/**
* Allocating function pointer type.
*
* @param opaque custom memory manager handle provided by client
* @param size requested memory region size; can not be @c 0
* @returns @c 0 in the case of failure
* @returns a valid pointer to a memory region of at least @p size bytes
* long otherwise
*/
typedef void* (*brotli_alloc_func)(void* opaque, size_t size);
/**
* Deallocating function pointer type.
*
* This function @b SHOULD do nothing if @p address is @c 0.
*
* @param opaque custom memory manager handle provided by client
* @param address memory region pointer returned by ::brotli_alloc_func, or @c 0
*/
typedef void (*brotli_free_func)(void* opaque, void* address);
#endif /* BROTLI_COMMON_TYPES_H_ */

View File

@ -1,9 +0,0 @@
def can_build(env, platform):
env.module_add_dependencies("freetype", ["png"], False)
return True
def configure(env):
pass

File diff suppressed because it is too large Load Diff

View File

@ -1,378 +0,0 @@
#ifndef DYNAMIC_FONT_H
#define DYNAMIC_FONT_H
/* dynamic_font.h */
#include "core/containers/pair.h"
#include "core/io/resource_loader.h"
#include "core/os/mutex.h"
#include "core/os/thread_safe.h"
#include "scene/resources/font/font.h"
#include "scene/resources/texture.h"
#include <ft2build.h>
#include FT_FREETYPE_H
class DynamicFontAtSize;
class DynamicFont;
class DynamicFontData : public Resource {
GDCLASS(DynamicFontData, Resource);
public:
struct CacheID {
union {
struct {
uint32_t size : 16;
uint32_t outline_size : 8;
uint32_t mipmaps : 1;
uint32_t filter : 1;
uint32_t unused : 6;
};
uint32_t key;
};
bool operator<(CacheID right) const;
CacheID() {
key = 0;
}
};
enum Hinting {
HINTING_NONE,
HINTING_LIGHT,
HINTING_NORMAL
};
bool is_antialiased() const;
void set_antialiased(bool p_antialiased);
Hinting get_hinting() const;
void set_hinting(Hinting p_hinting);
private:
const uint8_t *font_mem;
int font_mem_size;
bool antialiased;
bool force_autohinter;
Hinting hinting;
Vector<uint8_t> _fontdata;
float override_oversampling;
String font_path;
RBMap<CacheID, DynamicFontAtSize *> size_cache;
friend class DynamicFontAtSize;
friend class DynamicFont;
Ref<DynamicFontAtSize> _get_dynamic_font_at_size(CacheID p_cache_id);
protected:
static void _bind_methods();
public:
void set_font_ptr(const uint8_t *p_font_mem, int p_font_mem_size);
void set_font_path(const String &p_path);
String get_font_path() const;
void set_force_autohinter(bool p_force);
float get_override_oversampling() const;
void set_override_oversampling(float p_oversampling);
DynamicFontData();
~DynamicFontData();
};
VARIANT_ENUM_CAST(DynamicFontData::Hinting);
class DynamicFontAtSize : public Reference {
GDCLASS(DynamicFontAtSize, Reference);
_THREAD_SAFE_CLASS_
FT_Library library; /* handle to library */
FT_Face face; /* handle to face object */
FT_StreamRec stream;
float ascent;
float descent;
float linegap;
float rect_margin;
float oversampling;
float scale_color_font;
uint32_t texture_flags;
bool valid;
struct FontTexturePosition {
int32_t index = -1;
int32_t x = 0;
int32_t y = 0;
FontTexturePosition() {}
FontTexturePosition(int32_t p_id, int32_t p_x, int32_t p_y) :
index(p_id), x(p_x), y(p_y) {}
};
struct Shelf {
int32_t x = 0;
int32_t y = 0;
int32_t w = 0;
int32_t h = 0;
FontTexturePosition alloc_shelf(int32_t p_id, int32_t p_w, int32_t p_h) {
if (p_w > w || p_h > h) {
return FontTexturePosition(-1, 0, 0);
}
int32_t xx = x;
x += p_w;
w -= p_w;
return FontTexturePosition(p_id, xx, y);
}
Shelf() {}
Shelf(int32_t p_x, int32_t p_y, int32_t p_w, int32_t p_h) :
x(p_x), y(p_y), w(p_w), h(p_h) {}
};
struct ShelfPackTexture {
int32_t texture_size = 1024;
PoolVector<uint8_t> imgdata;
Ref<ImageTexture> texture;
List<Shelf> shelves;
Image::Format format;
bool dirty = true;
FontTexturePosition pack_rect(int32_t p_id, int32_t p_h, int32_t p_w) {
int32_t y = 0;
int32_t waste = 0;
List<Shelf>::Element *best_shelf = nullptr;
int32_t best_waste = std::numeric_limits<std::int32_t>::max();
for (List<Shelf>::Element *E = shelves.front(); E; E = E->next()) {
y += E->get().h;
if (p_w > E->get().w) {
continue;
}
if (p_h == E->get().h) {
return E->get().alloc_shelf(p_id, p_w, p_h);
}
if (p_h > E->get().h) {
continue;
}
if (p_h < E->get().h) {
waste = (E->get().h - p_h) * p_w;
if (waste < best_waste) {
best_waste = waste;
best_shelf = E;
}
}
}
if (best_shelf) {
return best_shelf->get().alloc_shelf(p_id, p_w, p_h);
}
if (p_h <= (texture_size - y) && p_w <= texture_size) {
List<Shelf>::Element *E = shelves.push_back(Shelf(0, y, texture_size, p_h));
return E->get().alloc_shelf(p_id, p_w, p_h);
}
return FontTexturePosition(-1, 0, 0);
}
ShelfPackTexture() {}
ShelfPackTexture(int32_t p_size) :
texture_size(p_size) {}
};
Vector<ShelfPackTexture> textures;
struct Character {
bool found;
int texture_idx;
Rect2 rect;
Rect2 rect_uv;
float v_align;
float h_align;
float advance;
Character() {
texture_idx = 0;
v_align = 0;
}
static Character not_found();
};
const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(int32_t p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
Character _make_outline_char(int32_t p_char);
float _get_kerning_advance(const DynamicFontAtSize *font, int32_t p_char, int32_t p_next) const;
FontTexturePosition _find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height);
Character _bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance);
HashMap<int32_t, Character> char_map;
_FORCE_INLINE_ void _update_char(int32_t p_char);
friend class DynamicFontData;
Ref<DynamicFontData> font;
DynamicFontData::CacheID id;
Error _load();
public:
static float font_oversampling;
float get_height() const;
float get_ascent() const;
float get_descent() const;
Size2 get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
String get_available_chars() const;
float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only = false, bool p_outline = false, MultiRect *p_multirect = NULL) const;
RID get_char_texture(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
Size2 get_char_texture_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
Vector2 get_char_tx_offset(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
Size2 get_char_tx_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
Rect2 get_char_tx_uv_rect(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
void set_texture_flags(uint32_t p_flags);
void update_oversampling();
Dictionary get_char_contours(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
DynamicFontAtSize();
~DynamicFontAtSize();
};
///////////////
class DynamicFont : public Font {
GDCLASS(DynamicFont, Font);
public:
enum SpacingType {
SPACING_TOP,
SPACING_BOTTOM,
SPACING_CHAR,
SPACING_SPACE
};
private:
Ref<DynamicFontData> data;
Ref<DynamicFontAtSize> data_at_size;
Ref<DynamicFontAtSize> outline_data_at_size;
Vector<Ref<DynamicFontData>> fallbacks;
Vector<Ref<DynamicFontAtSize>> fallback_data_at_size;
Vector<Ref<DynamicFontAtSize>> fallback_outline_data_at_size;
DynamicFontData::CacheID cache_id;
DynamicFontData::CacheID outline_cache_id;
bool valid;
int spacing_top;
int spacing_bottom;
int spacing_char;
int spacing_space;
Color outline_color;
protected:
void _reload_cache(const char *p_triggering_property = "");
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();
public:
void set_font_data(const Ref<DynamicFontData> &p_data);
Ref<DynamicFontData> get_font_data() const;
void set_size(int p_size);
int get_size() const;
void set_outline_size(int p_size);
int get_outline_size() const;
void set_outline_color(Color p_color);
Color get_outline_color() const;
bool get_use_mipmaps() const;
void set_use_mipmaps(bool p_enable);
bool get_use_filter() const;
void set_use_filter(bool p_enable);
int get_spacing(int p_type) const;
void set_spacing(int p_type, int p_value);
void add_fallback(const Ref<DynamicFontData> &p_data);
void set_fallback(int p_idx, const Ref<DynamicFontData> &p_data);
int get_fallback_count() const;
Ref<DynamicFontData> get_fallback(int p_idx) const;
void remove_fallback(int p_idx);
virtual float get_height() const;
virtual float get_ascent() const;
virtual float get_descent() const;
virtual int get_spacing_char() const;
virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const;
String get_available_chars() const;
virtual bool is_distance_field_hint() const;
virtual bool has_outline() const;
virtual float draw_char_ex(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false, MultiRect *p_multirect = NULL) const;
RID get_char_texture(CharType p_char, CharType p_next, bool p_outline) const;
Size2 get_char_texture_size(CharType p_char, CharType p_next, bool p_outline) const;
Vector2 get_char_tx_offset(CharType p_char, CharType p_next, bool p_outline) const;
Size2 get_char_tx_size(CharType p_char, CharType p_next, bool p_outline) const;
Rect2 get_char_tx_uv_rect(CharType p_char, CharType p_next, bool p_outline) const;
Dictionary get_char_contours(CharType p_char, CharType p_next) const;
SelfList<DynamicFont> font_list;
static Mutex dynamic_font_mutex;
static SelfList<DynamicFont>::List *dynamic_fonts;
static void initialize_dynamic_fonts();
static void finish_dynamic_fonts();
static void update_oversampling();
DynamicFont();
~DynamicFont();
};
VARIANT_ENUM_CAST(DynamicFont::SpacingType);
/////////////
class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader {
GDCLASS(ResourceFormatLoaderDynamicFont, ResourceFormatLoader);
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_no_subresource_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
void _scene_tree_update_font_oversampling(float p_ratio);
protected:
static void _bind_methods();
};
#endif // DYNAMIC_FONT_H

View File

@ -1,169 +0,0 @@
The FreeType Project LICENSE
----------------------------
2006-Jan-27
Copyright 1996-2002, 2006 by
David Turner, Robert Wilhelm, and Werner Lemberg
Introduction
============
The FreeType Project is distributed in several archive packages;
some of them may contain, in addition to the FreeType font engine,
various tools and contributions which rely on, or relate to, the
FreeType Project.
This license applies to all files found in such packages, and
which do not fall under their own explicit license. The license
affects thus the FreeType font engine, the test programs,
documentation and makefiles, at the very least.
This license was inspired by the BSD, Artistic, and IJG
(Independent JPEG Group) licenses, which all encourage inclusion
and use of free software in commercial and freeware products
alike. As a consequence, its main points are that:
o We don't promise that this software works. However, we will be
interested in any kind of bug reports. (`as is' distribution)
o You can use this software for whatever you want, in parts or
full form, without having to pay us. (`royalty-free' usage)
o You may not pretend that you wrote this software. If you use
it, or only parts of it, in a program, you must acknowledge
somewhere in your documentation that you have used the
FreeType code. (`credits')
We specifically permit and encourage the inclusion of this
software, with or without modifications, in commercial products.
We disclaim all warranties covering The FreeType Project and
assume no liability related to The FreeType Project.
Finally, many people asked us for a preferred form for a
credit/disclaimer to use in compliance with this license. We thus
encourage you to use the following text:
"""
Portions of this software are copyright © <year> The FreeType
Project (www.freetype.org). All rights reserved.
"""
Please replace <year> with the value from the FreeType version you
actually use.
Legal Terms
===========
0. Definitions
--------------
Throughout this license, the terms `package', `FreeType Project',
and `FreeType archive' refer to the set of files originally
distributed by the authors (David Turner, Robert Wilhelm, and
Werner Lemberg) as the `FreeType Project', be they named as alpha,
beta or final release.
`You' refers to the licensee, or person using the project, where
`using' is a generic term including compiling the project's source
code as well as linking it to form a `program' or `executable'.
This program is referred to as `a program using the FreeType
engine'.
This license applies to all files distributed in the original
FreeType Project, including all source code, binaries and
documentation, unless otherwise stated in the file in its
original, unmodified form as distributed in the original archive.
If you are unsure whether or not a particular file is covered by
this license, you must contact us to verify this.
The FreeType Project is copyright (C) 1996-2000 by David Turner,
Robert Wilhelm, and Werner Lemberg. All rights reserved except as
specified below.
1. No Warranty
--------------
THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
USE, OF THE FREETYPE PROJECT.
2. Redistribution
-----------------
This license grants a worldwide, royalty-free, perpetual and
irrevocable right and license to use, execute, perform, compile,
display, copy, create derivative works of, distribute and
sublicense the FreeType Project (in both source and object code
forms) and derivative works thereof for any purpose; and to
authorize others to exercise some or all of the rights granted
herein, subject to the following conditions:
o Redistribution of source code must retain this license file
(`FTL.TXT') unaltered; any additions, deletions or changes to
the original files must be clearly indicated in accompanying
documentation. The copyright notices of the unaltered,
original files must be preserved in all copies of source
files.
o Redistribution in binary form must provide a disclaimer that
states that the software is based in part of the work of the
FreeType Team, in the distribution documentation. We also
encourage you to put an URL to the FreeType web page in your
documentation, though this isn't mandatory.
These conditions apply to any software derived from or based on
the FreeType Project, not just the unmodified files. If you use
our work, you must acknowledge us. However, no fee need be paid
to us.
3. Advertising
--------------
Neither the FreeType authors and contributors nor you shall use
the name of the other for commercial, advertising, or promotional
purposes without specific prior written permission.
We suggest, but do not require, that you use one or more of the
following phrases to refer to this software in your documentation
or advertising materials: `FreeType Project', `FreeType Engine',
`FreeType library', or `FreeType Distribution'.
As you have not signed this license, you are not required to
accept it. However, as the FreeType Project is copyrighted
material, only this license, or another one contracted with the
authors, grants you the right to use, distribute, and modify it.
Therefore, by using, distributing, or modifying the FreeType
Project, you indicate that you understand and accept all the terms
of this license.
4. Contacts
-----------
There are two mailing lists related to FreeType:
o freetype@nongnu.org
Discusses general use and applications of FreeType, as well as
future and wanted additions to the library and distribution.
If you are looking for support, start in this list if you
haven't found anything to help you in the documentation.
o freetype-devel@nongnu.org
Discusses bugs, as well as engine internals, design issues,
specific licenses, porting, etc.
Our home page can be found at
https://www.freetype.org
--- end of FTL.TXT ---

View File

@ -1,42 +0,0 @@
FREETYPE LICENSES
-----------------
The FreeType 2 font engine is copyrighted work and cannot be used
legally without a software license. In order to make this project
usable to a vast majority of developers, we distribute it under two
mutually exclusive open-source licenses.
This means that *you* must choose *one* of the two licenses described
below, then obey all its terms and conditions when using FreeType 2 in
any of your projects or products.
- The FreeType License, found in the file `docs/FTL.TXT`, which is
similar to the original BSD license *with* an advertising clause
that forces you to explicitly cite the FreeType project in your
product's documentation. All details are in the license file.
This license is suited to products which don't use the GNU General
Public License.
Note that this license is compatible to the GNU General Public
License version 3, but not version 2.
- The GNU General Public License version 2, found in
`docs/GPLv2.TXT` (any later version can be used also), for
programs which already use the GPL. Note that the FTL is
incompatible with GPLv2 due to its advertisement clause.
The contributed BDF and PCF drivers come with a license similar to
that of the X Window System. It is compatible to the above two
licenses (see files `src/bdf/README` and `src/pcf/README`). The same
holds for the source code files `src/base/fthash.c` and
`include/freetype/internal/fthash.h`; they wer part of the BDF driver
in earlier FreeType versions.
The gzip module uses the zlib license (see `src/gzip/zlib.h`) which
too is compatible to the above two licenses.
The MD5 checksum support (only used for debugging in development
builds) is in the public domain.
--- end of LICENSE.TXT ---

View File

@ -1,51 +0,0 @@
/****************************************************************************
*
* ftconfig.h
*
* ANSI-specific configuration file (specification only).
*
* Copyright (C) 1996-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This header file contains a number of macro definitions that are used by
* the rest of the engine. Most of the macros here are automatically
* determined at compile time, and you should not need to change it to port
* FreeType, except to compile the library with a non-ANSI compiler.
*
* Note however that if some specific modifications are needed, we advise
* you to place a modified copy in your build directory.
*
* The build directory is usually `builds/<system>`, and contains
* system-specific files that are always included first when building the
* library.
*
* This ANSI version should stay in `include/config/`.
*
*/
#ifndef FTCONFIG_H_
#define FTCONFIG_H_
#include <ft2build.h>
#include FT_CONFIG_OPTIONS_H
#include FT_CONFIG_STANDARD_LIBRARY_H
#include <freetype/config/integer-types.h>
#include <freetype/config/public-macros.h>
#include <freetype/config/mac-support.h>
#endif /* FTCONFIG_H_ */
/* END */

View File

@ -1,836 +0,0 @@
/****************************************************************************
*
* ftheader.h
*
* Build macros of the FreeType 2 library.
*
* Copyright (C) 1996-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTHEADER_H_
#define FTHEADER_H_
/*@***********************************************************************/
/* */
/* <Macro> */
/* FT_BEGIN_HEADER */
/* */
/* <Description> */
/* This macro is used in association with @FT_END_HEADER in header */
/* files to ensure that the declarations within are properly */
/* encapsulated in an `extern "C" { .. }` block when included from a */
/* C++ compiler. */
/* */
#ifndef FT_BEGIN_HEADER
# ifdef __cplusplus
# define FT_BEGIN_HEADER extern "C" {
# else
# define FT_BEGIN_HEADER /* nothing */
# endif
#endif
/*@***********************************************************************/
/* */
/* <Macro> */
/* FT_END_HEADER */
/* */
/* <Description> */
/* This macro is used in association with @FT_BEGIN_HEADER in header */
/* files to ensure that the declarations within are properly */
/* encapsulated in an `extern "C" { .. }` block when included from a */
/* C++ compiler. */
/* */
#ifndef FT_END_HEADER
# ifdef __cplusplus
# define FT_END_HEADER }
# else
# define FT_END_HEADER /* nothing */
# endif
#endif
/**************************************************************************
*
* Aliases for the FreeType 2 public and configuration files.
*
*/
/**************************************************************************
*
* @section:
* header_file_macros
*
* @title:
* Header File Macros
*
* @abstract:
* Macro definitions used to `#include` specific header files.
*
* @description:
* In addition to the normal scheme of including header files like
*
* ```
* #include <freetype/freetype.h>
* #include <freetype/ftmm.h>
* #include <freetype/ftglyph.h>
* ```
*
* it is possible to used named macros instead. They can be used
* directly in `#include` statements as in
*
* ```
* #include FT_FREETYPE_H
* #include FT_MULTIPLE_MASTERS_H
* #include FT_GLYPH_H
* ```
*
* These macros were introduced to overcome the infamous 8.3~naming rule
* required by DOS (and `FT_MULTIPLE_MASTERS_H` is a lot more meaningful
* than `ftmm.h`).
*
*/
/* configuration files */
/**************************************************************************
*
* @macro:
* FT_CONFIG_CONFIG_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* FreeType~2 configuration data.
*
*/
#ifndef FT_CONFIG_CONFIG_H
#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h>
#endif
/**************************************************************************
*
* @macro:
* FT_CONFIG_STANDARD_LIBRARY_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* FreeType~2 interface to the standard C library functions.
*
*/
#ifndef FT_CONFIG_STANDARD_LIBRARY_H
#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h>
#endif
/**************************************************************************
*
* @macro:
* FT_CONFIG_OPTIONS_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* FreeType~2 project-specific configuration options.
*
*/
#ifndef FT_CONFIG_OPTIONS_H
#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h>
#endif
/**************************************************************************
*
* @macro:
* FT_CONFIG_MODULES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* list of FreeType~2 modules that are statically linked to new library
* instances in @FT_Init_FreeType.
*
*/
#ifndef FT_CONFIG_MODULES_H
#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h>
#endif
/* */
/* public headers */
/**************************************************************************
*
* @macro:
* FT_FREETYPE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* base FreeType~2 API.
*
*/
#define FT_FREETYPE_H <freetype/freetype.h>
/**************************************************************************
*
* @macro:
* FT_ERRORS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* list of FreeType~2 error codes (and messages).
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_ERRORS_H <freetype/fterrors.h>
/**************************************************************************
*
* @macro:
* FT_MODULE_ERRORS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* list of FreeType~2 module error offsets (and messages).
*
*/
#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h>
/**************************************************************************
*
* @macro:
* FT_SYSTEM_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 interface to low-level operations (i.e., memory management
* and stream i/o).
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_SYSTEM_H <freetype/ftsystem.h>
/**************************************************************************
*
* @macro:
* FT_IMAGE_H
*
* @description:
* A macro used in `#include` statements to name the file containing type
* definitions related to glyph images (i.e., bitmaps, outlines,
* scan-converter parameters).
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_IMAGE_H <freetype/ftimage.h>
/**************************************************************************
*
* @macro:
* FT_TYPES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* basic data types defined by FreeType~2.
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_TYPES_H <freetype/fttypes.h>
/**************************************************************************
*
* @macro:
* FT_LIST_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* list management API of FreeType~2.
*
* (Most applications will never need to include this file.)
*
*/
#define FT_LIST_H <freetype/ftlist.h>
/**************************************************************************
*
* @macro:
* FT_OUTLINE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* scalable outline management API of FreeType~2.
*
*/
#define FT_OUTLINE_H <freetype/ftoutln.h>
/**************************************************************************
*
* @macro:
* FT_SIZES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API which manages multiple @FT_Size objects per face.
*
*/
#define FT_SIZES_H <freetype/ftsizes.h>
/**************************************************************************
*
* @macro:
* FT_MODULE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* module management API of FreeType~2.
*
*/
#define FT_MODULE_H <freetype/ftmodapi.h>
/**************************************************************************
*
* @macro:
* FT_RENDER_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* renderer module management API of FreeType~2.
*
*/
#define FT_RENDER_H <freetype/ftrender.h>
/**************************************************************************
*
* @macro:
* FT_DRIVER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the driver modules.
*
*/
#define FT_DRIVER_H <freetype/ftdriver.h>
/**************************************************************************
*
* @macro:
* FT_AUTOHINTER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the auto-hinting module.
*
* Deprecated since version~2.9; use @FT_DRIVER_H instead.
*
*/
#define FT_AUTOHINTER_H FT_DRIVER_H
/**************************************************************************
*
* @macro:
* FT_CFF_DRIVER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the CFF driver module.
*
* Deprecated since version~2.9; use @FT_DRIVER_H instead.
*
*/
#define FT_CFF_DRIVER_H FT_DRIVER_H
/**************************************************************************
*
* @macro:
* FT_TRUETYPE_DRIVER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the TrueType driver module.
*
* Deprecated since version~2.9; use @FT_DRIVER_H instead.
*
*/
#define FT_TRUETYPE_DRIVER_H FT_DRIVER_H
/**************************************************************************
*
* @macro:
* FT_PCF_DRIVER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the PCF driver module.
*
* Deprecated since version~2.9; use @FT_DRIVER_H instead.
*
*/
#define FT_PCF_DRIVER_H FT_DRIVER_H
/**************************************************************************
*
* @macro:
* FT_TYPE1_TABLES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* types and API specific to the Type~1 format.
*
*/
#define FT_TYPE1_TABLES_H <freetype/t1tables.h>
/**************************************************************************
*
* @macro:
* FT_TRUETYPE_IDS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* enumeration values which identify name strings, languages, encodings,
* etc. This file really contains a _large_ set of constant macro
* definitions, taken from the TrueType and OpenType specifications.
*
*/
#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h>
/**************************************************************************
*
* @macro:
* FT_TRUETYPE_TABLES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* types and API specific to the TrueType (as well as OpenType) format.
*
*/
#define FT_TRUETYPE_TABLES_H <freetype/tttables.h>
/**************************************************************************
*
* @macro:
* FT_TRUETYPE_TAGS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of TrueType four-byte 'tags' which identify blocks in
* SFNT-based font formats (i.e., TrueType and OpenType).
*
*/
#define FT_TRUETYPE_TAGS_H <freetype/tttags.h>
/**************************************************************************
*
* @macro:
* FT_BDF_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which accesses BDF-specific strings from a face.
*
*/
#define FT_BDF_H <freetype/ftbdf.h>
/**************************************************************************
*
* @macro:
* FT_CID_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which access CID font information from a face.
*
*/
#define FT_CID_H <freetype/ftcid.h>
/**************************************************************************
*
* @macro:
* FT_GZIP_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which supports gzip-compressed files.
*
*/
#define FT_GZIP_H <freetype/ftgzip.h>
/**************************************************************************
*
* @macro:
* FT_LZW_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which supports LZW-compressed files.
*
*/
#define FT_LZW_H <freetype/ftlzw.h>
/**************************************************************************
*
* @macro:
* FT_BZIP2_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which supports bzip2-compressed files.
*
*/
#define FT_BZIP2_H <freetype/ftbzip2.h>
/**************************************************************************
*
* @macro:
* FT_WINFONTS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which supports Windows FNT files.
*
*/
#define FT_WINFONTS_H <freetype/ftwinfnt.h>
/**************************************************************************
*
* @macro:
* FT_GLYPH_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of the optional glyph management component.
*
*/
#define FT_GLYPH_H <freetype/ftglyph.h>
/**************************************************************************
*
* @macro:
* FT_BITMAP_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of the optional bitmap conversion component.
*
*/
#define FT_BITMAP_H <freetype/ftbitmap.h>
/**************************************************************************
*
* @macro:
* FT_BBOX_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of the optional exact bounding box computation routines.
*
*/
#define FT_BBOX_H <freetype/ftbbox.h>
/**************************************************************************
*
* @macro:
* FT_CACHE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of the optional FreeType~2 cache sub-system.
*
*/
#define FT_CACHE_H <freetype/ftcache.h>
/**************************************************************************
*
* @macro:
* FT_MAC_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* Macintosh-specific FreeType~2 API. The latter is used to access fonts
* embedded in resource forks.
*
* This header file must be explicitly included by client applications
* compiled on the Mac (note that the base API still works though).
*
*/
#define FT_MAC_H <freetype/ftmac.h>
/**************************************************************************
*
* @macro:
* FT_MULTIPLE_MASTERS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* optional multiple-masters management API of FreeType~2.
*
*/
#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h>
/**************************************************************************
*
* @macro:
* FT_SFNT_NAMES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* optional FreeType~2 API which accesses embedded 'name' strings in
* SFNT-based font formats (i.e., TrueType and OpenType).
*
*/
#define FT_SFNT_NAMES_H <freetype/ftsnames.h>
/**************************************************************************
*
* @macro:
* FT_OPENTYPE_VALIDATE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* optional FreeType~2 API which validates OpenType tables ('BASE',
* 'GDEF', 'GPOS', 'GSUB', 'JSTF').
*
*/
#define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h>
/**************************************************************************
*
* @macro:
* FT_GX_VALIDATE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* optional FreeType~2 API which validates TrueTypeGX/AAT tables ('feat',
* 'mort', 'morx', 'bsln', 'just', 'kern', 'opbd', 'trak', 'prop').
*
*/
#define FT_GX_VALIDATE_H <freetype/ftgxval.h>
/**************************************************************************
*
* @macro:
* FT_PFR_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which accesses PFR-specific data.
*
*/
#define FT_PFR_H <freetype/ftpfr.h>
/**************************************************************************
*
* @macro:
* FT_STROKER_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which provides functions to stroke outline paths.
*/
#define FT_STROKER_H <freetype/ftstroke.h>
/**************************************************************************
*
* @macro:
* FT_SYNTHESIS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which performs artificial obliquing and emboldening.
*/
#define FT_SYNTHESIS_H <freetype/ftsynth.h>
/**************************************************************************
*
* @macro:
* FT_FONT_FORMATS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which provides functions specific to font formats.
*/
#define FT_FONT_FORMATS_H <freetype/ftfntfmt.h>
/* deprecated */
#define FT_XFREE86_H FT_FONT_FORMATS_H
/**************************************************************************
*
* @macro:
* FT_TRIGONOMETRY_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which performs trigonometric computations (e.g.,
* cosines and arc tangents).
*/
#define FT_TRIGONOMETRY_H <freetype/fttrigon.h>
/**************************************************************************
*
* @macro:
* FT_LCD_FILTER_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which performs color filtering for subpixel rendering.
*/
#define FT_LCD_FILTER_H <freetype/ftlcdfil.h>
/**************************************************************************
*
* @macro:
* FT_INCREMENTAL_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which performs incremental glyph loading.
*/
#define FT_INCREMENTAL_H <freetype/ftincrem.h>
/**************************************************************************
*
* @macro:
* FT_GASP_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which returns entries from the TrueType GASP table.
*/
#define FT_GASP_H <freetype/ftgasp.h>
/**************************************************************************
*
* @macro:
* FT_ADVANCES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which returns individual and ranged glyph advances.
*/
#define FT_ADVANCES_H <freetype/ftadvanc.h>
/**************************************************************************
*
* @macro:
* FT_COLOR_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which handles the OpenType 'CPAL' table.
*/
#define FT_COLOR_H <freetype/ftcolor.h>
/**************************************************************************
*
* @macro:
* FT_OTSVG_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which handles the OpenType 'SVG~' glyphs.
*/
#define FT_OTSVG_H <freetype/otsvg.h>
/* */
/* These header files don't need to be included by the user. */
#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h>
#define FT_PARAMETER_TAGS_H <freetype/ftparams.h>
/* Deprecated macros. */
#define FT_UNPATENTED_HINTING_H <freetype/ftparams.h>
#define FT_TRUETYPE_UNPATENTED_H <freetype/ftparams.h>
/* `FT_CACHE_H` is the only header file needed for the cache subsystem. */
#define FT_CACHE_IMAGE_H FT_CACHE_H
#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H
#define FT_CACHE_CHARMAP_H FT_CACHE_H
/* The internals of the cache sub-system are no longer exposed. We */
/* default to `FT_CACHE_H` at the moment just in case, but we know */
/* of no rogue client that uses them. */
/* */
#define FT_CACHE_MANAGER_H FT_CACHE_H
#define FT_CACHE_INTERNAL_MRU_H FT_CACHE_H
#define FT_CACHE_INTERNAL_MANAGER_H FT_CACHE_H
#define FT_CACHE_INTERNAL_CACHE_H FT_CACHE_H
#define FT_CACHE_INTERNAL_GLYPH_H FT_CACHE_H
#define FT_CACHE_INTERNAL_IMAGE_H FT_CACHE_H
#define FT_CACHE_INTERNAL_SBITS_H FT_CACHE_H
/* TODO(david): Move this section below to a different header */
#ifdef FT2_BUILD_LIBRARY
#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
/* We disable the warning `conditional expression is constant' here */
/* in order to compile cleanly with the maximum level of warnings. */
/* In particular, the warning complains about stuff like `while(0)' */
/* which is very useful in macro definitions. There is no benefit */
/* in having it enabled. */
#pragma warning( disable : 4127 )
#endif /* _MSC_VER */
#endif /* FT2_BUILD_LIBRARY */
#endif /* FTHEADER_H_ */
/* END */

View File

@ -1,33 +0,0 @@
/*
* This file registers the FreeType modules compiled into the library.
*
* If you use GNU make, this file IS NOT USED! Instead, it is created in
* the objects directory (normally `<topdir>/objs/`) based on information
* from `<topdir>/modules.cfg`.
*
* Please read `docs/INSTALL.ANY` and `docs/CUSTOMIZE` how to compile
* FreeType without GNU make.
*
*/
FT_USE_MODULE( FT_Module_Class, autofit_module_class )
FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
FT_USE_MODULE( FT_Module_Class, psaux_module_class )
FT_USE_MODULE( FT_Module_Class, psnames_module_class )
FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_svg_renderer_class )
/* EOF */

File diff suppressed because it is too large Load Diff

View File

@ -1,185 +0,0 @@
/****************************************************************************
*
* ftstdlib.h
*
* ANSI-specific library and header configuration file (specification
* only).
*
* Copyright (C) 2002-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This file is used to group all `#includes` to the ANSI~C library that
* FreeType normally requires. It also defines macros to rename the
* standard functions within the FreeType source code.
*
* Load a file which defines `FTSTDLIB_H_` before this one to override it.
*
*/
#ifndef FTSTDLIB_H_
#define FTSTDLIB_H_
#include <stddef.h>
#define ft_ptrdiff_t ptrdiff_t
/**************************************************************************
*
* integer limits
*
* `UINT_MAX` and `ULONG_MAX` are used to automatically compute the size of
* `int` and `long` in bytes at compile-time. So far, this works for all
* platforms the library has been tested on. We also check `ULLONG_MAX`
* to see whether we can use 64-bit `long long` later on.
*
* Note that on the extremely rare platforms that do not provide integer
* types that are _exactly_ 16 and 32~bits wide (e.g., some old Crays where
* `int` is 36~bits), we do not make any guarantee about the correct
* behaviour of FreeType~2 with all fonts.
*
* In these cases, `ftconfig.h` will refuse to compile anyway with a
* message like 'couldn't find 32-bit type' or something similar.
*
*/
#include <limits.h>
#define FT_CHAR_BIT CHAR_BIT
#define FT_USHORT_MAX USHRT_MAX
#define FT_INT_MAX INT_MAX
#define FT_INT_MIN INT_MIN
#define FT_UINT_MAX UINT_MAX
#define FT_LONG_MIN LONG_MIN
#define FT_LONG_MAX LONG_MAX
#define FT_ULONG_MAX ULONG_MAX
#ifdef LLONG_MAX
#define FT_LLONG_MAX LLONG_MAX
#endif
#ifdef LLONG_MIN
#define FT_LLONG_MIN LLONG_MIN
#endif
#ifdef ULLONG_MAX
#define FT_ULLONG_MAX ULLONG_MAX
#endif
/**************************************************************************
*
* character and string processing
*
*/
#include <string.h>
#define ft_memchr memchr
#define ft_memcmp memcmp
#define ft_memcpy memcpy
#define ft_memmove memmove
#define ft_memset memset
#define ft_strcat strcat
#define ft_strcmp strcmp
#define ft_strcpy strcpy
#define ft_strlen strlen
#define ft_strncmp strncmp
#define ft_strncpy strncpy
#define ft_strrchr strrchr
#define ft_strstr strstr
/**************************************************************************
*
* file handling
*
*/
#include <stdio.h>
#define FT_FILE FILE
#define ft_fclose fclose
#define ft_fopen fopen
#define ft_fread fread
#define ft_fseek fseek
#define ft_ftell ftell
#define ft_sprintf sprintf
/**************************************************************************
*
* sorting
*
*/
#include <stdlib.h>
#define ft_qsort qsort
/**************************************************************************
*
* memory allocation
*
*/
#define ft_scalloc calloc
#define ft_sfree free
#define ft_smalloc malloc
#define ft_srealloc realloc
/**************************************************************************
*
* miscellaneous
*
*/
#define ft_strtol strtol
#define ft_getenv getenv
/**************************************************************************
*
* execution control
*
*/
#include <setjmp.h>
#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */
/* `jmp_buf` is defined as a macro */
/* on certain platforms */
#define ft_longjmp longjmp
#define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */
/* The following is only used for debugging purposes, i.e., if */
/* `FT_DEBUG_LEVEL_ERROR` or `FT_DEBUG_LEVEL_TRACE` are defined. */
#include <stdarg.h>
#endif /* FTSTDLIB_H_ */
/* END */

View File

@ -1,250 +0,0 @@
/****************************************************************************
*
* config/integer-types.h
*
* FreeType integer types definitions.
*
* Copyright (C) 1996-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FREETYPE_CONFIG_INTEGER_TYPES_H_
#define FREETYPE_CONFIG_INTEGER_TYPES_H_
/* There are systems (like the Texas Instruments 'C54x) where a `char` */
/* has 16~bits. ANSI~C says that `sizeof(char)` is always~1. Since an */
/* `int` has 16~bits also for this system, `sizeof(int)` gives~1 which */
/* is probably unexpected. */
/* */
/* `CHAR_BIT` (defined in `limits.h`) gives the number of bits in a */
/* `char` type. */
#ifndef FT_CHAR_BIT
#define FT_CHAR_BIT CHAR_BIT
#endif
#ifndef FT_SIZEOF_INT
/* The size of an `int` type. */
#if FT_UINT_MAX == 0xFFFFUL
#define FT_SIZEOF_INT ( 16 / FT_CHAR_BIT )
#elif FT_UINT_MAX == 0xFFFFFFFFUL
#define FT_SIZEOF_INT ( 32 / FT_CHAR_BIT )
#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
#define FT_SIZEOF_INT ( 64 / FT_CHAR_BIT )
#else
#error "Unsupported size of `int' type!"
#endif
#endif /* !defined(FT_SIZEOF_INT) */
#ifndef FT_SIZEOF_LONG
/* The size of a `long` type. A five-byte `long` (as used e.g. on the */
/* DM642) is recognized but avoided. */
#if FT_ULONG_MAX == 0xFFFFFFFFUL
#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT )
#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT )
#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
#define FT_SIZEOF_LONG ( 64 / FT_CHAR_BIT )
#else
#error "Unsupported size of `long' type!"
#endif
#endif /* !defined(FT_SIZEOF_LONG) */
#ifndef FT_SIZEOF_LONG_LONG
/* The size of a `long long` type if available */
#if defined( FT_ULLONG_MAX ) && FT_ULLONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
#define FT_SIZEOF_LONG_LONG ( 64 / FT_CHAR_BIT )
#else
#define FT_SIZEOF_LONG_LONG 0
#endif
#endif /* !defined(FT_SIZEOF_LONG_LONG) */
/**************************************************************************
*
* @section:
* basic_types
*
*/
/**************************************************************************
*
* @type:
* FT_Int16
*
* @description:
* A typedef for a 16bit signed integer type.
*/
typedef signed short FT_Int16;
/**************************************************************************
*
* @type:
* FT_UInt16
*
* @description:
* A typedef for a 16bit unsigned integer type.
*/
typedef unsigned short FT_UInt16;
/* */
/* this #if 0 ... #endif clause is for documentation purposes */
#if 0
/**************************************************************************
*
* @type:
* FT_Int32
*
* @description:
* A typedef for a 32bit signed integer type. The size depends on the
* configuration.
*/
typedef signed XXX FT_Int32;
/**************************************************************************
*
* @type:
* FT_UInt32
*
* A typedef for a 32bit unsigned integer type. The size depends on the
* configuration.
*/
typedef unsigned XXX FT_UInt32;
/**************************************************************************
*
* @type:
* FT_Int64
*
* A typedef for a 64bit signed integer type. The size depends on the
* configuration. Only defined if there is real 64bit support;
* otherwise, it gets emulated with a structure (if necessary).
*/
typedef signed XXX FT_Int64;
/**************************************************************************
*
* @type:
* FT_UInt64
*
* A typedef for a 64bit unsigned integer type. The size depends on the
* configuration. Only defined if there is real 64bit support;
* otherwise, it gets emulated with a structure (if necessary).
*/
typedef unsigned XXX FT_UInt64;
/* */
#endif
#if FT_SIZEOF_INT == ( 32 / FT_CHAR_BIT )
typedef signed int FT_Int32;
typedef unsigned int FT_UInt32;
#elif FT_SIZEOF_LONG == ( 32 / FT_CHAR_BIT )
typedef signed long FT_Int32;
typedef unsigned long FT_UInt32;
#else
#error "no 32bit type found -- please check your configuration files"
#endif
/* look up an integer type that is at least 32~bits */
#if FT_SIZEOF_INT >= ( 32 / FT_CHAR_BIT )
typedef int FT_Fast;
typedef unsigned int FT_UFast;
#elif FT_SIZEOF_LONG >= ( 32 / FT_CHAR_BIT )
typedef long FT_Fast;
typedef unsigned long FT_UFast;
#endif
/* determine whether we have a 64-bit integer type */
#if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT )
#define FT_INT64 long
#define FT_UINT64 unsigned long
#elif FT_SIZEOF_LONG_LONG >= ( 64 / FT_CHAR_BIT )
#define FT_INT64 long long int
#define FT_UINT64 unsigned long long int
/**************************************************************************
*
* A 64-bit data type may create compilation problems if you compile in
* strict ANSI mode. To avoid them, we disable other 64-bit data types if
* `__STDC__` is defined. You can however ignore this rule by defining the
* `FT_CONFIG_OPTION_FORCE_INT64` configuration macro.
*/
#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
/* this compiler provides the `__int64` type */
#define FT_INT64 __int64
#define FT_UINT64 unsigned __int64
#elif defined( __BORLANDC__ ) /* Borland C++ */
/* XXXX: We should probably check the value of `__BORLANDC__` in order */
/* to test the compiler version. */
/* this compiler provides the `__int64` type */
#define FT_INT64 __int64
#define FT_UINT64 unsigned __int64
#elif defined( __WATCOMC__ ) && __WATCOMC__ >= 1100 /* Watcom C++ */
#define FT_INT64 long long int
#define FT_UINT64 unsigned long long int
#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */
#define FT_INT64 long long int
#define FT_UINT64 unsigned long long int
#elif defined( __GNUC__ )
/* GCC provides the `long long` type */
#define FT_INT64 long long int
#define FT_UINT64 unsigned long long int
#endif /* !__STDC__ */
#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
#ifdef FT_INT64
typedef FT_INT64 FT_Int64;
typedef FT_UINT64 FT_UInt64;
#endif
#endif /* FREETYPE_CONFIG_INTEGER_TYPES_H_ */

View File

@ -1,49 +0,0 @@
/****************************************************************************
*
* config/mac-support.h
*
* Mac/OS X support configuration header.
*
* Copyright (C) 1996-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FREETYPE_CONFIG_MAC_SUPPORT_H_
#define FREETYPE_CONFIG_MAC_SUPPORT_H_
/**************************************************************************
*
* Mac support
*
* This is the only necessary change, so it is defined here instead
* providing a new configuration file.
*/
#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) )
/* No Carbon frameworks for 64bit 10.4.x. */
/* `AvailabilityMacros.h` is available since Mac OS X 10.2, */
/* so guess the system version by maximum errno before inclusion. */
#include <errno.h>
#ifdef ECANCELED /* defined since 10.2 */
#include "AvailabilityMacros.h"
#endif
#if defined( __LP64__ ) && \
( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
#undef FT_MACINTOSH
#endif
#elif defined( __SC__ ) || defined( __MRC__ )
/* Classic MacOS compilers */
#include "ConditionalMacros.h"
#if TARGET_OS_MAC
#define FT_MACINTOSH 1
#endif
#endif /* Mac support */
#endif /* FREETYPE_CONFIG_MAC_SUPPORT_H_ */

View File

@ -1,138 +0,0 @@
/****************************************************************************
*
* config/public-macros.h
*
* Define a set of compiler macros used in public FreeType headers.
*
* Copyright (C) 2020-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/*
* The definitions in this file are used by the public FreeType headers
* and thus should be considered part of the public API.
*
* Other compiler-specific macro definitions that are not exposed by the
* FreeType API should go into
* `include/freetype/internal/compiler-macros.h` instead.
*/
#ifndef FREETYPE_CONFIG_PUBLIC_MACROS_H_
#define FREETYPE_CONFIG_PUBLIC_MACROS_H_
/*
* `FT_BEGIN_HEADER` and `FT_END_HEADER` might have already been defined
* by `freetype/config/ftheader.h`, but we don't want to include this
* header here, so redefine the macros here only when needed. Their
* definition is very stable, so keeping them in sync with the ones in the
* header should not be a maintenance issue.
*/
#ifndef FT_BEGIN_HEADER
#ifdef __cplusplus
#define FT_BEGIN_HEADER extern "C" {
#else
#define FT_BEGIN_HEADER /* empty */
#endif
#endif /* FT_BEGIN_HEADER */
#ifndef FT_END_HEADER
#ifdef __cplusplus
#define FT_END_HEADER }
#else
#define FT_END_HEADER /* empty */
#endif
#endif /* FT_END_HEADER */
FT_BEGIN_HEADER
/*
* Mark a function declaration as public. This ensures it will be
* properly exported to client code. Place this before a function
* declaration.
*
* NOTE: This macro should be considered an internal implementation
* detail, and not part of the FreeType API. It is only defined here
* because it is needed by `FT_EXPORT`.
*/
/* Visual C, mingw */
#if defined( _WIN32 )
#if defined( FT2_BUILD_LIBRARY ) && defined( DLL_EXPORT )
#define FT_PUBLIC_FUNCTION_ATTRIBUTE __declspec( dllexport )
#elif defined( DLL_IMPORT )
#define FT_PUBLIC_FUNCTION_ATTRIBUTE __declspec( dllimport )
#endif
/* gcc, clang */
#elif ( defined( __GNUC__ ) && __GNUC__ >= 4 ) || defined( __clang__ )
#define FT_PUBLIC_FUNCTION_ATTRIBUTE \
__attribute__(( visibility( "default" ) ))
/* Sun */
#elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
#define FT_PUBLIC_FUNCTION_ATTRIBUTE __global
#endif
#ifndef FT_PUBLIC_FUNCTION_ATTRIBUTE
#define FT_PUBLIC_FUNCTION_ATTRIBUTE /* empty */
#endif
/*
* Define a public FreeType API function. This ensures it is properly
* exported or imported at build time. The macro parameter is the
* function's return type as in:
*
* FT_EXPORT( FT_Bool )
* FT_Object_Method( FT_Object obj,
* ... );
*
* NOTE: This requires that all `FT_EXPORT` uses are inside
* `FT_BEGIN_HEADER ... FT_END_HEADER` blocks. This guarantees that the
* functions are exported with C linkage, even when the header is included
* by a C++ source file.
*/
#define FT_EXPORT( x ) FT_PUBLIC_FUNCTION_ATTRIBUTE extern x
/*
* `FT_UNUSED` indicates that a given parameter is not used -- this is
* only used to get rid of unpleasant compiler warnings.
*
* Technically, this was not meant to be part of the public API, but some
* third-party code depends on it.
*/
#ifndef FT_UNUSED
#define FT_UNUSED( arg ) ( (arg) = (arg) )
#endif
/*
* Support for casts in both C and C++.
*/
#ifdef __cplusplus
#define FT_STATIC_CAST( type, var ) static_cast<type>(var)
#define FT_REINTERPRET_CAST( type, var ) reinterpret_cast<type>(var)
#define FT_STATIC_BYTE_CAST( type, var ) \
static_cast<type>( static_cast<unsigned char>( var ) )
#else
#define FT_STATIC_CAST( type, var ) (type)(var)
#define FT_REINTERPRET_CAST( type, var ) (type)(var)
#define FT_STATIC_BYTE_CAST( type, var ) (type)(unsigned char)(var)
#endif
FT_END_HEADER
#endif /* FREETYPE_CONFIG_PUBLIC_MACROS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,188 +0,0 @@
/****************************************************************************
*
* ftadvanc.h
*
* Quick computation of advance widths (specification only).
*
* Copyright (C) 2008-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTADVANC_H_
#define FTADVANC_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* quick_advance
*
* @title:
* Quick retrieval of advance values
*
* @abstract:
* Retrieve horizontal and vertical advance values without processing
* glyph outlines, if possible.
*
* @description:
* This section contains functions to quickly extract advance values
* without handling glyph outlines, if possible.
*
* @order:
* FT_Get_Advance
* FT_Get_Advances
*
*/
/**************************************************************************
*
* @enum:
* FT_ADVANCE_FLAG_FAST_ONLY
*
* @description:
* A bit-flag to be OR-ed with the `flags` parameter of the
* @FT_Get_Advance and @FT_Get_Advances functions.
*
* If set, it indicates that you want these functions to fail if the
* corresponding hinting mode or font driver doesn't allow for very quick
* advance computation.
*
* Typically, glyphs that are either unscaled, unhinted, bitmapped, or
* light-hinted can have their advance width computed very quickly.
*
* Normal and bytecode hinted modes that require loading, scaling, and
* hinting of the glyph outline, are extremely slow by comparison.
*/
#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000L
/**************************************************************************
*
* @function:
* FT_Get_Advance
*
* @description:
* Retrieve the advance value of a given glyph outline in an @FT_Face.
*
* @input:
* face ::
* The source @FT_Face handle.
*
* gindex ::
* The glyph index.
*
* load_flags ::
* A set of bit flags similar to those used when calling
* @FT_Load_Glyph, used to determine what kind of advances you need.
*
* @output:
* padvance ::
* The advance value. If scaling is performed (based on the value of
* `load_flags`), the advance value is in 16.16 format. Otherwise, it
* is in font units.
*
* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the vertical advance
* corresponding to a vertical layout. Otherwise, it is the horizontal
* advance in a horizontal layout.
*
* @return:
* FreeType error code. 0 means success.
*
* @note:
* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and if
* the corresponding font backend doesn't have a quick way to retrieve
* the advances.
*
* A scaled advance is returned in 16.16 format but isn't transformed by
* the affine transformation specified by @FT_Set_Transform.
*/
FT_EXPORT( FT_Error )
FT_Get_Advance( FT_Face face,
FT_UInt gindex,
FT_Int32 load_flags,
FT_Fixed *padvance );
/**************************************************************************
*
* @function:
* FT_Get_Advances
*
* @description:
* Retrieve the advance values of several glyph outlines in an @FT_Face.
*
* @input:
* face ::
* The source @FT_Face handle.
*
* start ::
* The first glyph index.
*
* count ::
* The number of advance values you want to retrieve.
*
* load_flags ::
* A set of bit flags similar to those used when calling
* @FT_Load_Glyph.
*
* @output:
* padvance ::
* The advance values. This array, to be provided by the caller, must
* contain at least `count` elements.
*
* If scaling is performed (based on the value of `load_flags`), the
* advance values are in 16.16 format. Otherwise, they are in font
* units.
*
* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the vertical advances
* corresponding to a vertical layout. Otherwise, they are the
* horizontal advances in a horizontal layout.
*
* @return:
* FreeType error code. 0 means success.
*
* @note:
* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and if
* the corresponding font backend doesn't have a quick way to retrieve
* the advances.
*
* Scaled advances are returned in 16.16 format but aren't transformed by
* the affine transformation specified by @FT_Set_Transform.
*/
FT_EXPORT( FT_Error )
FT_Get_Advances( FT_Face face,
FT_UInt start,
FT_UInt count,
FT_Int32 load_flags,
FT_Fixed *padvances );
/* */
FT_END_HEADER
#endif /* FTADVANC_H_ */
/* END */

View File

@ -1,101 +0,0 @@
/****************************************************************************
*
* ftbbox.h
*
* FreeType exact bbox computation (specification).
*
* Copyright (C) 1996-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This component has a _single_ role: to compute exact outline bounding
* boxes.
*
* It is separated from the rest of the engine for various technical
* reasons. It may well be integrated in 'ftoutln' later.
*
*/
#ifndef FTBBOX_H_
#define FTBBOX_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* outline_processing
*
*/
/**************************************************************************
*
* @function:
* FT_Outline_Get_BBox
*
* @description:
* Compute the exact bounding box of an outline. This is slower than
* computing the control box. However, it uses an advanced algorithm
* that returns _very_ quickly when the two boxes coincide. Otherwise,
* the outline Bezier arcs are traversed to extract their extrema.
*
* @input:
* outline ::
* A pointer to the source outline.
*
* @output:
* abbox ::
* The outline's exact bounding box.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* If the font is tricky and the glyph has been loaded with
* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get
* reasonable values for the BBox it is necessary to load the glyph at a
* large ppem value (so that the hinting instructions can properly shift
* and scale the subglyphs), then extracting the BBox, which can be
* eventually converted back to font units.
*/
FT_EXPORT( FT_Error )
FT_Outline_Get_BBox( FT_Outline* outline,
FT_BBox *abbox );
/* */
FT_END_HEADER
#endif /* FTBBOX_H_ */
/* END */
/* Local Variables: */
/* coding: utf-8 */
/* End: */

View File

@ -1,212 +0,0 @@
/****************************************************************************
*
* ftbdf.h
*
* FreeType API for accessing BDF-specific strings (specification).
*
* Copyright (C) 2002-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTBDF_H_
#define FTBDF_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* bdf_fonts
*
* @title:
* BDF and PCF Files
*
* @abstract:
* BDF and PCF specific API.
*
* @description:
* This section contains the declaration of functions specific to BDF and
* PCF fonts.
*
*/
/**************************************************************************
*
* @enum:
* BDF_PropertyType
*
* @description:
* A list of BDF property types.
*
* @values:
* BDF_PROPERTY_TYPE_NONE ::
* Value~0 is used to indicate a missing property.
*
* BDF_PROPERTY_TYPE_ATOM ::
* Property is a string atom.
*
* BDF_PROPERTY_TYPE_INTEGER ::
* Property is a 32-bit signed integer.
*
* BDF_PROPERTY_TYPE_CARDINAL ::
* Property is a 32-bit unsigned integer.
*/
typedef enum BDF_PropertyType_
{
BDF_PROPERTY_TYPE_NONE = 0,
BDF_PROPERTY_TYPE_ATOM = 1,
BDF_PROPERTY_TYPE_INTEGER = 2,
BDF_PROPERTY_TYPE_CARDINAL = 3
} BDF_PropertyType;
/**************************************************************************
*
* @type:
* BDF_Property
*
* @description:
* A handle to a @BDF_PropertyRec structure to model a given BDF/PCF
* property.
*/
typedef struct BDF_PropertyRec_* BDF_Property;
/**************************************************************************
*
* @struct:
* BDF_PropertyRec
*
* @description:
* This structure models a given BDF/PCF property.
*
* @fields:
* type ::
* The property type.
*
* u.atom ::
* The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. May be
* `NULL`, indicating an empty string.
*
* u.integer ::
* A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER.
*
* u.cardinal ::
* An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL.
*/
typedef struct BDF_PropertyRec_
{
BDF_PropertyType type;
union {
const char* atom;
FT_Int32 integer;
FT_UInt32 cardinal;
} u;
} BDF_PropertyRec;
/**************************************************************************
*
* @function:
* FT_Get_BDF_Charset_ID
*
* @description:
* Retrieve a BDF font character set identity, according to the BDF
* specification.
*
* @input:
* face ::
* A handle to the input face.
*
* @output:
* acharset_encoding ::
* Charset encoding, as a C~string, owned by the face.
*
* acharset_registry ::
* Charset registry, as a C~string, owned by the face.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function only works with BDF faces, returning an error otherwise.
*/
FT_EXPORT( FT_Error )
FT_Get_BDF_Charset_ID( FT_Face face,
const char* *acharset_encoding,
const char* *acharset_registry );
/**************************************************************************
*
* @function:
* FT_Get_BDF_Property
*
* @description:
* Retrieve a BDF property from a BDF or PCF font file.
*
* @input:
* face ::
* A handle to the input face.
*
* name ::
* The property name.
*
* @output:
* aproperty ::
* The property.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function works with BDF _and_ PCF fonts. It returns an error
* otherwise. It also returns an error if the property is not in the
* font.
*
* A 'property' is a either key-value pair within the STARTPROPERTIES
* ... ENDPROPERTIES block of a BDF font or a key-value pair from the
* `info->props` array within a `FontRec` structure of a PCF font.
*
* Integer properties are always stored as 'signed' within PCF fonts;
* consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value
* for BDF fonts only.
*
* In case of error, `aproperty->type` is always set to
* @BDF_PROPERTY_TYPE_NONE.
*/
FT_EXPORT( FT_Error )
FT_Get_BDF_Property( FT_Face face,
const char* prop_name,
BDF_PropertyRec *aproperty );
/* */
FT_END_HEADER
#endif /* FTBDF_H_ */
/* END */

View File

@ -1,329 +0,0 @@
/****************************************************************************
*
* ftbitmap.h
*
* FreeType utility functions for bitmaps (specification).
*
* Copyright (C) 2004-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTBITMAP_H_
#define FTBITMAP_H_
#include <freetype/freetype.h>
#include <freetype/ftcolor.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* bitmap_handling
*
* @title:
* Bitmap Handling
*
* @abstract:
* Handling FT_Bitmap objects.
*
* @description:
* This section contains functions for handling @FT_Bitmap objects,
* automatically adjusting the target's bitmap buffer size as needed.
*
* Note that none of the functions changes the bitmap's 'flow' (as
* indicated by the sign of the `pitch` field in @FT_Bitmap).
*
* To set the flow, assign an appropriate positive or negative value to
* the `pitch` field of the target @FT_Bitmap object after calling
* @FT_Bitmap_Init but before calling any of the other functions
* described here.
*/
/**************************************************************************
*
* @function:
* FT_Bitmap_Init
*
* @description:
* Initialize a pointer to an @FT_Bitmap structure.
*
* @inout:
* abitmap ::
* A pointer to the bitmap structure.
*
* @note:
* A deprecated name for the same function is `FT_Bitmap_New`.
*/
FT_EXPORT( void )
FT_Bitmap_Init( FT_Bitmap *abitmap );
/* deprecated */
FT_EXPORT( void )
FT_Bitmap_New( FT_Bitmap *abitmap );
/**************************************************************************
*
* @function:
* FT_Bitmap_Copy
*
* @description:
* Copy a bitmap into another one.
*
* @input:
* library ::
* A handle to a library object.
*
* source ::
* A handle to the source bitmap.
*
* @output:
* target ::
* A handle to the target bitmap.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* `source->buffer` and `target->buffer` must neither be equal nor
* overlap.
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Copy( FT_Library library,
const FT_Bitmap *source,
FT_Bitmap *target );
/**************************************************************************
*
* @function:
* FT_Bitmap_Embolden
*
* @description:
* Embolden a bitmap. The new bitmap will be about `xStrength` pixels
* wider and `yStrength` pixels higher. The left and bottom borders are
* kept unchanged.
*
* @input:
* library ::
* A handle to a library object.
*
* xStrength ::
* How strong the glyph is emboldened horizontally. Expressed in 26.6
* pixel format.
*
* yStrength ::
* How strong the glyph is emboldened vertically. Expressed in 26.6
* pixel format.
*
* @inout:
* bitmap ::
* A handle to the target bitmap.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The current implementation restricts `xStrength` to be less than or
* equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO.
*
* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, you
* should call @FT_GlyphSlot_Own_Bitmap on the slot first.
*
* Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format are
* converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp).
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Embolden( FT_Library library,
FT_Bitmap* bitmap,
FT_Pos xStrength,
FT_Pos yStrength );
/**************************************************************************
*
* @function:
* FT_Bitmap_Convert
*
* @description:
* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp to
* a bitmap object with depth 8bpp, making the number of used bytes per
* line (a.k.a. the 'pitch') a multiple of `alignment`.
*
* @input:
* library ::
* A handle to a library object.
*
* source ::
* The source bitmap.
*
* alignment ::
* The pitch of the bitmap is a multiple of this argument. Common
* values are 1, 2, or 4.
*
* @output:
* target ::
* The target bitmap.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* It is possible to call @FT_Bitmap_Convert multiple times without
* calling @FT_Bitmap_Done (the memory is simply reallocated).
*
* Use @FT_Bitmap_Done to finally remove the bitmap object.
*
* The `library` argument is taken to have access to FreeType's memory
* handling functions.
*
* `source->buffer` and `target->buffer` must neither be equal nor
* overlap.
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Convert( FT_Library library,
const FT_Bitmap *source,
FT_Bitmap *target,
FT_Int alignment );
/**************************************************************************
*
* @function:
* FT_Bitmap_Blend
*
* @description:
* Blend a bitmap onto another bitmap, using a given color.
*
* @input:
* library ::
* A handle to a library object.
*
* source ::
* The source bitmap, which can have any @FT_Pixel_Mode format.
*
* source_offset ::
* The offset vector to the upper left corner of the source bitmap in
* 26.6 pixel format. It should represent an integer offset; the
* function will set the lowest six bits to zero to enforce that.
*
* color ::
* The color used to draw `source` onto `target`.
*
* @inout:
* target ::
* A handle to an `FT_Bitmap` object. It should be either initialized
* as empty with a call to @FT_Bitmap_Init, or it should be of type
* @FT_PIXEL_MODE_BGRA.
*
* atarget_offset ::
* The offset vector to the upper left corner of the target bitmap in
* 26.6 pixel format. It should represent an integer offset; the
* function will set the lowest six bits to zero to enforce that.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function doesn't perform clipping.
*
* The bitmap in `target` gets allocated or reallocated as needed; the
* vector `atarget_offset` is updated accordingly.
*
* In case of allocation or reallocation, the bitmap's pitch is set to
* `4 * width`. Both `source` and `target` must have the same bitmap
* flow (as indicated by the sign of the `pitch` field).
*
* `source->buffer` and `target->buffer` must neither be equal nor
* overlap.
*
* @since:
* 2.10
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Blend( FT_Library library,
const FT_Bitmap* source,
const FT_Vector source_offset,
FT_Bitmap* target,
FT_Vector *atarget_offset,
FT_Color color );
/**************************************************************************
*
* @function:
* FT_GlyphSlot_Own_Bitmap
*
* @description:
* Make sure that a glyph slot owns `slot->bitmap`.
*
* @input:
* slot ::
* The glyph slot.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function is to be used in combination with @FT_Bitmap_Embolden.
*/
FT_EXPORT( FT_Error )
FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot );
/**************************************************************************
*
* @function:
* FT_Bitmap_Done
*
* @description:
* Destroy a bitmap object initialized with @FT_Bitmap_Init.
*
* @input:
* library ::
* A handle to a library object.
*
* bitmap ::
* The bitmap object to be freed.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The `library` argument is taken to have access to FreeType's memory
* handling functions.
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Done( FT_Library library,
FT_Bitmap *bitmap );
/* */
FT_END_HEADER
#endif /* FTBITMAP_H_ */
/* END */

View File

@ -1,102 +0,0 @@
/****************************************************************************
*
* ftbzip2.h
*
* Bzip2-compressed stream support.
*
* Copyright (C) 2010-2022 by
* Joel Klinghed.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTBZIP2_H_
#define FTBZIP2_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* bzip2
*
* @title:
* BZIP2 Streams
*
* @abstract:
* Using bzip2-compressed font files.
*
* @description:
* In certain builds of the library, bzip2 compression recognition is
* automatically handled when calling @FT_New_Face or @FT_Open_Face.
* This means that if no font driver is capable of handling the raw
* compressed file, the library will try to open a bzip2 compressed
* stream from it and re-open the face with it.
*
* The stream implementation is very basic and resets the decompression
* process each time seeking backwards is needed within the stream,
* which significantly undermines the performance.
*
* This section contains the declaration of Bzip2-specific functions.
*
*/
/**************************************************************************
*
* @function:
* FT_Stream_OpenBzip2
*
* @description:
* Open a new stream to parse bzip2-compressed font files. This is
* mainly used to support the compressed `*.pcf.bz2` fonts that come with
* XFree86.
*
* @input:
* stream ::
* The target embedding stream.
*
* source ::
* The source stream.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The source stream must be opened _before_ calling this function.
*
* Calling the internal function `FT_Stream_Close` on the new stream will
* **not** call `FT_Stream_Close` on the source stream. None of the
* stream objects will be released to the heap.
*
* This function may return `FT_Err_Unimplemented_Feature` if your build
* of FreeType was not compiled with bzip2 support.
*/
FT_EXPORT( FT_Error )
FT_Stream_OpenBzip2( FT_Stream stream,
FT_Stream source );
/* */
FT_END_HEADER
#endif /* FTBZIP2_H_ */
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -1,149 +0,0 @@
/****************************************************************************
*
* This file defines the structure of the FreeType reference.
* It is used by the python script that generates the HTML files.
*
*/
/**************************************************************************
*
* @chapter:
* general_remarks
*
* @title:
* General Remarks
*
* @sections:
* preamble
* header_inclusion
* user_allocation
*
*/
/**************************************************************************
*
* @chapter:
* core_api
*
* @title:
* Core API
*
* @sections:
* version
* basic_types
* base_interface
* glyph_variants
* color_management
* layer_management
* glyph_management
* mac_specific
* sizes_management
* header_file_macros
*
*/
/**************************************************************************
*
* @chapter:
* format_specific
*
* @title:
* Format-Specific API
*
* @sections:
* multiple_masters
* truetype_tables
* type1_tables
* sfnt_names
* bdf_fonts
* cid_fonts
* pfr_fonts
* winfnt_fonts
* svg_fonts
* font_formats
* gasp_table
*
*/
/**************************************************************************
*
* @chapter:
* module_specific
*
* @title:
* Controlling FreeType Modules
*
* @sections:
* auto_hinter
* cff_driver
* t1_cid_driver
* tt_driver
* pcf_driver
* ot_svg_driver
* properties
* parameter_tags
* lcd_rendering
*
*/
/**************************************************************************
*
* @chapter:
* cache_subsystem
*
* @title:
* Cache Sub-System
*
* @sections:
* cache_subsystem
*
*/
/**************************************************************************
*
* @chapter:
* support_api
*
* @title:
* Support API
*
* @sections:
* computations
* list_processing
* outline_processing
* quick_advance
* bitmap_handling
* raster
* glyph_stroker
* system_interface
* module_management
* gzip
* lzw
* bzip2
* debugging_apis
*
*/
/**************************************************************************
*
* @chapter:
* error_codes
*
* @title:
* Error Codes
*
* @sections:
* error_enumerations
* error_code_values
*
*/
/* END */

View File

@ -1,167 +0,0 @@
/****************************************************************************
*
* ftcid.h
*
* FreeType API for accessing CID font information (specification).
*
* Copyright (C) 2007-2022 by
* Dereg Clegg and Michael Toftdal.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTCID_H_
#define FTCID_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* cid_fonts
*
* @title:
* CID Fonts
*
* @abstract:
* CID-keyed font-specific API.
*
* @description:
* This section contains the declaration of CID-keyed font-specific
* functions.
*
*/
/**************************************************************************
*
* @function:
* FT_Get_CID_Registry_Ordering_Supplement
*
* @description:
* Retrieve the Registry/Ordering/Supplement triple (also known as the
* "R/O/S") from a CID-keyed font.
*
* @input:
* face ::
* A handle to the input face.
*
* @output:
* registry ::
* The registry, as a C~string, owned by the face.
*
* ordering ::
* The ordering, as a C~string, owned by the face.
*
* supplement ::
* The supplement.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function only works with CID faces, returning an error
* otherwise.
*
* @since:
* 2.3.6
*/
FT_EXPORT( FT_Error )
FT_Get_CID_Registry_Ordering_Supplement( FT_Face face,
const char* *registry,
const char* *ordering,
FT_Int *supplement );
/**************************************************************************
*
* @function:
* FT_Get_CID_Is_Internally_CID_Keyed
*
* @description:
* Retrieve the type of the input face, CID keyed or not. In contrast
* to the @FT_IS_CID_KEYED macro this function returns successfully also
* for CID-keyed fonts in an SFNT wrapper.
*
* @input:
* face ::
* A handle to the input face.
*
* @output:
* is_cid ::
* The type of the face as an @FT_Bool.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function only works with CID faces and OpenType fonts, returning
* an error otherwise.
*
* @since:
* 2.3.9
*/
FT_EXPORT( FT_Error )
FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face,
FT_Bool *is_cid );
/**************************************************************************
*
* @function:
* FT_Get_CID_From_Glyph_Index
*
* @description:
* Retrieve the CID of the input glyph index.
*
* @input:
* face ::
* A handle to the input face.
*
* glyph_index ::
* The input glyph index.
*
* @output:
* cid ::
* The CID as an @FT_UInt.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function only works with CID faces and OpenType fonts, returning
* an error otherwise.
*
* @since:
* 2.3.9
*/
FT_EXPORT( FT_Error )
FT_Get_CID_From_Glyph_Index( FT_Face face,
FT_UInt glyph_index,
FT_UInt *cid );
/* */
FT_END_HEADER
#endif /* FTCID_H_ */
/* END */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,283 +0,0 @@
/****************************************************************************
*
* fterrdef.h
*
* FreeType error codes (specification).
*
* Copyright (C) 2002-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* @section:
* error_code_values
*
* @title:
* Error Code Values
*
* @abstract:
* All possible error codes returned by FreeType functions.
*
* @description:
* The list below is taken verbatim from the file `fterrdef.h` (loaded
* automatically by including `FT_FREETYPE_H`). The first argument of the
* `FT_ERROR_DEF_` macro is the error label; by default, the prefix
* `FT_Err_` gets added so that you get error names like
* `FT_Err_Cannot_Open_Resource`. The second argument is the error code,
* and the last argument an error string, which is not used by FreeType.
*
* Within your application you should **only** use error names and
* **never** its numeric values! The latter might (and actually do)
* change in forthcoming FreeType versions.
*
* Macro `FT_NOERRORDEF_` defines `FT_Err_Ok`, which is always zero. See
* the 'Error Enumerations' subsection how to automatically generate a
* list of error strings.
*
*/
/**************************************************************************
*
* @enum:
* FT_Err_XXX
*
*/
/* generic errors */
FT_NOERRORDEF_( Ok, 0x00,
"no error" )
FT_ERRORDEF_( Cannot_Open_Resource, 0x01,
"cannot open resource" )
FT_ERRORDEF_( Unknown_File_Format, 0x02,
"unknown file format" )
FT_ERRORDEF_( Invalid_File_Format, 0x03,
"broken file" )
FT_ERRORDEF_( Invalid_Version, 0x04,
"invalid FreeType version" )
FT_ERRORDEF_( Lower_Module_Version, 0x05,
"module version is too low" )
FT_ERRORDEF_( Invalid_Argument, 0x06,
"invalid argument" )
FT_ERRORDEF_( Unimplemented_Feature, 0x07,
"unimplemented feature" )
FT_ERRORDEF_( Invalid_Table, 0x08,
"broken table" )
FT_ERRORDEF_( Invalid_Offset, 0x09,
"broken offset within table" )
FT_ERRORDEF_( Array_Too_Large, 0x0A,
"array allocation size too large" )
FT_ERRORDEF_( Missing_Module, 0x0B,
"missing module" )
FT_ERRORDEF_( Missing_Property, 0x0C,
"missing property" )
/* glyph/character errors */
FT_ERRORDEF_( Invalid_Glyph_Index, 0x10,
"invalid glyph index" )
FT_ERRORDEF_( Invalid_Character_Code, 0x11,
"invalid character code" )
FT_ERRORDEF_( Invalid_Glyph_Format, 0x12,
"unsupported glyph image format" )
FT_ERRORDEF_( Cannot_Render_Glyph, 0x13,
"cannot render this glyph format" )
FT_ERRORDEF_( Invalid_Outline, 0x14,
"invalid outline" )
FT_ERRORDEF_( Invalid_Composite, 0x15,
"invalid composite glyph" )
FT_ERRORDEF_( Too_Many_Hints, 0x16,
"too many hints" )
FT_ERRORDEF_( Invalid_Pixel_Size, 0x17,
"invalid pixel size" )
FT_ERRORDEF_( Invalid_SVG_Document, 0x18,
"invalid SVG document" )
/* handle errors */
FT_ERRORDEF_( Invalid_Handle, 0x20,
"invalid object handle" )
FT_ERRORDEF_( Invalid_Library_Handle, 0x21,
"invalid library handle" )
FT_ERRORDEF_( Invalid_Driver_Handle, 0x22,
"invalid module handle" )
FT_ERRORDEF_( Invalid_Face_Handle, 0x23,
"invalid face handle" )
FT_ERRORDEF_( Invalid_Size_Handle, 0x24,
"invalid size handle" )
FT_ERRORDEF_( Invalid_Slot_Handle, 0x25,
"invalid glyph slot handle" )
FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26,
"invalid charmap handle" )
FT_ERRORDEF_( Invalid_Cache_Handle, 0x27,
"invalid cache manager handle" )
FT_ERRORDEF_( Invalid_Stream_Handle, 0x28,
"invalid stream handle" )
/* driver errors */
FT_ERRORDEF_( Too_Many_Drivers, 0x30,
"too many modules" )
FT_ERRORDEF_( Too_Many_Extensions, 0x31,
"too many extensions" )
/* memory errors */
FT_ERRORDEF_( Out_Of_Memory, 0x40,
"out of memory" )
FT_ERRORDEF_( Unlisted_Object, 0x41,
"unlisted object" )
/* stream errors */
FT_ERRORDEF_( Cannot_Open_Stream, 0x51,
"cannot open stream" )
FT_ERRORDEF_( Invalid_Stream_Seek, 0x52,
"invalid stream seek" )
FT_ERRORDEF_( Invalid_Stream_Skip, 0x53,
"invalid stream skip" )
FT_ERRORDEF_( Invalid_Stream_Read, 0x54,
"invalid stream read" )
FT_ERRORDEF_( Invalid_Stream_Operation, 0x55,
"invalid stream operation" )
FT_ERRORDEF_( Invalid_Frame_Operation, 0x56,
"invalid frame operation" )
FT_ERRORDEF_( Nested_Frame_Access, 0x57,
"nested frame access" )
FT_ERRORDEF_( Invalid_Frame_Read, 0x58,
"invalid frame read" )
/* raster errors */
FT_ERRORDEF_( Raster_Uninitialized, 0x60,
"raster uninitialized" )
FT_ERRORDEF_( Raster_Corrupted, 0x61,
"raster corrupted" )
FT_ERRORDEF_( Raster_Overflow, 0x62,
"raster overflow" )
FT_ERRORDEF_( Raster_Negative_Height, 0x63,
"negative height while rastering" )
/* cache errors */
FT_ERRORDEF_( Too_Many_Caches, 0x70,
"too many registered caches" )
/* TrueType and SFNT errors */
FT_ERRORDEF_( Invalid_Opcode, 0x80,
"invalid opcode" )
FT_ERRORDEF_( Too_Few_Arguments, 0x81,
"too few arguments" )
FT_ERRORDEF_( Stack_Overflow, 0x82,
"stack overflow" )
FT_ERRORDEF_( Code_Overflow, 0x83,
"code overflow" )
FT_ERRORDEF_( Bad_Argument, 0x84,
"bad argument" )
FT_ERRORDEF_( Divide_By_Zero, 0x85,
"division by zero" )
FT_ERRORDEF_( Invalid_Reference, 0x86,
"invalid reference" )
FT_ERRORDEF_( Debug_OpCode, 0x87,
"found debug opcode" )
FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88,
"found ENDF opcode in execution stream" )
FT_ERRORDEF_( Nested_DEFS, 0x89,
"nested DEFS" )
FT_ERRORDEF_( Invalid_CodeRange, 0x8A,
"invalid code range" )
FT_ERRORDEF_( Execution_Too_Long, 0x8B,
"execution context too long" )
FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C,
"too many function definitions" )
FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D,
"too many instruction definitions" )
FT_ERRORDEF_( Table_Missing, 0x8E,
"SFNT font table missing" )
FT_ERRORDEF_( Horiz_Header_Missing, 0x8F,
"horizontal header (hhea) table missing" )
FT_ERRORDEF_( Locations_Missing, 0x90,
"locations (loca) table missing" )
FT_ERRORDEF_( Name_Table_Missing, 0x91,
"name table missing" )
FT_ERRORDEF_( CMap_Table_Missing, 0x92,
"character map (cmap) table missing" )
FT_ERRORDEF_( Hmtx_Table_Missing, 0x93,
"horizontal metrics (hmtx) table missing" )
FT_ERRORDEF_( Post_Table_Missing, 0x94,
"PostScript (post) table missing" )
FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95,
"invalid horizontal metrics" )
FT_ERRORDEF_( Invalid_CharMap_Format, 0x96,
"invalid character map (cmap) format" )
FT_ERRORDEF_( Invalid_PPem, 0x97,
"invalid ppem value" )
FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98,
"invalid vertical metrics" )
FT_ERRORDEF_( Could_Not_Find_Context, 0x99,
"could not find context" )
FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A,
"invalid PostScript (post) table format" )
FT_ERRORDEF_( Invalid_Post_Table, 0x9B,
"invalid PostScript (post) table" )
FT_ERRORDEF_( DEF_In_Glyf_Bytecode, 0x9C,
"found FDEF or IDEF opcode in glyf bytecode" )
FT_ERRORDEF_( Missing_Bitmap, 0x9D,
"missing bitmap in strike" )
FT_ERRORDEF_( Missing_SVG_Hooks, 0x9E,
"SVG hooks have not been set" )
/* CFF, CID, and Type 1 errors */
FT_ERRORDEF_( Syntax_Error, 0xA0,
"opcode syntax error" )
FT_ERRORDEF_( Stack_Underflow, 0xA1,
"argument stack underflow" )
FT_ERRORDEF_( Ignore, 0xA2,
"ignore" )
FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3,
"no Unicode glyph name found" )
FT_ERRORDEF_( Glyph_Too_Big, 0xA4,
"glyph too big for hinting" )
/* BDF errors */
FT_ERRORDEF_( Missing_Startfont_Field, 0xB0,
"`STARTFONT' field missing" )
FT_ERRORDEF_( Missing_Font_Field, 0xB1,
"`FONT' field missing" )
FT_ERRORDEF_( Missing_Size_Field, 0xB2,
"`SIZE' field missing" )
FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3,
"`FONTBOUNDINGBOX' field missing" )
FT_ERRORDEF_( Missing_Chars_Field, 0xB4,
"`CHARS' field missing" )
FT_ERRORDEF_( Missing_Startchar_Field, 0xB5,
"`STARTCHAR' field missing" )
FT_ERRORDEF_( Missing_Encoding_Field, 0xB6,
"`ENCODING' field missing" )
FT_ERRORDEF_( Missing_Bbx_Field, 0xB7,
"`BBX' field missing" )
FT_ERRORDEF_( Bbx_Too_Big, 0xB8,
"`BBX' too big" )
FT_ERRORDEF_( Corrupted_Font_Header, 0xB9,
"Font header corrupted or missing fields" )
FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA,
"Font glyphs corrupted or missing fields" )
/* */
/* END */

View File

@ -1,296 +0,0 @@
/****************************************************************************
*
* fterrors.h
*
* FreeType error code handling (specification).
*
* Copyright (C) 1996-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* @section:
* error_enumerations
*
* @title:
* Error Enumerations
*
* @abstract:
* How to handle errors and error strings.
*
* @description:
* The header file `fterrors.h` (which is automatically included by
* `freetype.h` defines the handling of FreeType's enumeration
* constants. It can also be used to generate error message strings
* with a small macro trick explained below.
*
* **Error Formats**
*
* The configuration macro `FT_CONFIG_OPTION_USE_MODULE_ERRORS` can be
* defined in `ftoption.h` in order to make the higher byte indicate the
* module where the error has happened (this is not compatible with
* standard builds of FreeType~2, however). See the file `ftmoderr.h`
* for more details.
*
* **Error Message Strings**
*
* Error definitions are set up with special macros that allow client
* applications to build a table of error message strings. The strings
* are not included in a normal build of FreeType~2 to save space (most
* client applications do not use them).
*
* To do so, you have to define the following macros before including
* this file.
*
* ```
* FT_ERROR_START_LIST
* ```
*
* This macro is called before anything else to define the start of the
* error list. It is followed by several `FT_ERROR_DEF` calls.
*
* ```
* FT_ERROR_DEF( e, v, s )
* ```
*
* This macro is called to define one single error. 'e' is the error
* code identifier (e.g., `Invalid_Argument`), 'v' is the error's
* numerical value, and 's' is the corresponding error string.
*
* ```
* FT_ERROR_END_LIST
* ```
*
* This macro ends the list.
*
* Additionally, you have to undefine `FTERRORS_H_` before #including
* this file.
*
* Here is a simple example.
*
* ```
* #undef FTERRORS_H_
* #define FT_ERRORDEF( e, v, s ) { e, s },
* #define FT_ERROR_START_LIST {
* #define FT_ERROR_END_LIST { 0, NULL } };
*
* const struct
* {
* int err_code;
* const char* err_msg;
* } ft_errors[] =
*
* #include <freetype/fterrors.h>
* ```
*
* An alternative to using an array is a switch statement.
*
* ```
* #undef FTERRORS_H_
* #define FT_ERROR_START_LIST switch ( error_code ) {
* #define FT_ERRORDEF( e, v, s ) case v: return s;
* #define FT_ERROR_END_LIST }
* ```
*
* If you use `FT_CONFIG_OPTION_USE_MODULE_ERRORS`, `error_code` should
* be replaced with `FT_ERROR_BASE(error_code)` in the last example.
*/
/* */
/* In previous FreeType versions we used `__FTERRORS_H__`. However, */
/* using two successive underscores in a non-system symbol name */
/* violates the C (and C++) standard, so it was changed to the */
/* current form. In spite of this, we have to make */
/* */
/* ``` */
/* #undefine __FTERRORS_H__ */
/* ``` */
/* */
/* work for backward compatibility. */
/* */
#if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) )
#define FTERRORS_H_
#define __FTERRORS_H__
/* include module base error codes */
#include <freetype/ftmoderr.h>
/*******************************************************************/
/*******************************************************************/
/***** *****/
/***** SETUP MACROS *****/
/***** *****/
/*******************************************************************/
/*******************************************************************/
#undef FT_NEED_EXTERN_C
/* FT_ERR_PREFIX is used as a prefix for error identifiers. */
/* By default, we use `FT_Err_`. */
/* */
#ifndef FT_ERR_PREFIX
#define FT_ERR_PREFIX FT_Err_
#endif
/* FT_ERR_BASE is used as the base for module-specific errors. */
/* */
#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS
#ifndef FT_ERR_BASE
#define FT_ERR_BASE FT_Mod_Err_Base
#endif
#else
#undef FT_ERR_BASE
#define FT_ERR_BASE 0
#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */
/* If FT_ERRORDEF is not defined, we need to define a simple */
/* enumeration type. */
/* */
#ifndef FT_ERRORDEF
#define FT_INCLUDE_ERR_PROTOS
#define FT_ERRORDEF( e, v, s ) e = v,
#define FT_ERROR_START_LIST enum {
#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) };
#ifdef __cplusplus
#define FT_NEED_EXTERN_C
extern "C" {
#endif
#endif /* !FT_ERRORDEF */
/* this macro is used to define an error */
#define FT_ERRORDEF_( e, v, s ) \
FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s )
/* this is only used for <module>_Err_Ok, which must be 0! */
#define FT_NOERRORDEF_( e, v, s ) \
FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s )
#ifdef FT_ERROR_START_LIST
FT_ERROR_START_LIST
#endif
/* now include the error codes */
#include <freetype/fterrdef.h>
#ifdef FT_ERROR_END_LIST
FT_ERROR_END_LIST
#endif
/*******************************************************************/
/*******************************************************************/
/***** *****/
/***** SIMPLE CLEANUP *****/
/***** *****/
/*******************************************************************/
/*******************************************************************/
#ifdef FT_NEED_EXTERN_C
}
#endif
#undef FT_ERROR_START_LIST
#undef FT_ERROR_END_LIST
#undef FT_ERRORDEF
#undef FT_ERRORDEF_
#undef FT_NOERRORDEF_
#undef FT_NEED_EXTERN_C
#undef FT_ERR_BASE
/* FT_ERR_PREFIX is needed internally */
#ifndef FT2_BUILD_LIBRARY
#undef FT_ERR_PREFIX
#endif
/* FT_INCLUDE_ERR_PROTOS: Control whether function prototypes should be */
/* included with */
/* */
/* #include <freetype/fterrors.h> */
/* */
/* This is only true where `FT_ERRORDEF` is */
/* undefined. */
/* */
/* FT_ERR_PROTOS_DEFINED: Actual multiple-inclusion protection of */
/* `fterrors.h`. */
#ifdef FT_INCLUDE_ERR_PROTOS
#undef FT_INCLUDE_ERR_PROTOS
#ifndef FT_ERR_PROTOS_DEFINED
#define FT_ERR_PROTOS_DEFINED
FT_BEGIN_HEADER
/**************************************************************************
*
* @function:
* FT_Error_String
*
* @description:
* Retrieve the description of a valid FreeType error code.
*
* @input:
* error_code ::
* A valid FreeType error code.
*
* @return:
* A C~string or `NULL`, if any error occurred.
*
* @note:
* FreeType has to be compiled with `FT_CONFIG_OPTION_ERROR_STRINGS` or
* `FT_DEBUG_LEVEL_ERROR` to get meaningful descriptions.
* 'error_string' will be `NULL` otherwise.
*
* Module identification will be ignored:
*
* ```c
* strcmp( FT_Error_String( FT_Err_Unknown_File_Format ),
* FT_Error_String( BDF_Err_Unknown_File_Format ) ) == 0;
* ```
*/
FT_EXPORT( const char* )
FT_Error_String( FT_Error error_code );
/* */
FT_END_HEADER
#endif /* FT_ERR_PROTOS_DEFINED */
#endif /* FT_INCLUDE_ERR_PROTOS */
#endif /* !(FTERRORS_H_ && __FTERRORS_H__) */
/* END */

View File

@ -1,93 +0,0 @@
/****************************************************************************
*
* ftfntfmt.h
*
* Support functions for font formats.
*
* Copyright (C) 2002-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTFNTFMT_H_
#define FTFNTFMT_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* font_formats
*
* @title:
* Font Formats
*
* @abstract:
* Getting the font format.
*
* @description:
* The single function in this section can be used to get the font format.
* Note that this information is not needed normally; however, there are
* special cases (like in PDF devices) where it is important to
* differentiate, in spite of FreeType's uniform API.
*
*/
/**************************************************************************
*
* @function:
* FT_Get_Font_Format
*
* @description:
* Return a string describing the format of a given face. Possible values
* are 'TrueType', 'Type~1', 'BDF', 'PCF', 'Type~42', 'CID~Type~1', 'CFF',
* 'PFR', and 'Windows~FNT'.
*
* The return value is suitable to be used as an X11 FONT_PROPERTY.
*
* @input:
* face ::
* Input face handle.
*
* @return:
* Font format string. `NULL` in case of error.
*
* @note:
* A deprecated name for the same function is `FT_Get_X11_Font_Format`.
*/
FT_EXPORT( const char* )
FT_Get_Font_Format( FT_Face face );
/* deprecated */
FT_EXPORT( const char* )
FT_Get_X11_Font_Format( FT_Face face );
/* */
FT_END_HEADER
#endif /* FTFNTFMT_H_ */
/* END */

View File

@ -1,143 +0,0 @@
/****************************************************************************
*
* ftgasp.h
*
* Access of TrueType's 'gasp' table (specification).
*
* Copyright (C) 2007-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTGASP_H_
#define FTGASP_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* gasp_table
*
* @title:
* Gasp Table
*
* @abstract:
* Retrieving TrueType 'gasp' table entries.
*
* @description:
* The function @FT_Get_Gasp can be used to query a TrueType or OpenType
* font for specific entries in its 'gasp' table, if any. This is mainly
* useful when implementing native TrueType hinting with the bytecode
* interpreter to duplicate the Windows text rendering results.
*/
/**************************************************************************
*
* @enum:
* FT_GASP_XXX
*
* @description:
* A list of values and/or bit-flags returned by the @FT_Get_Gasp
* function.
*
* @values:
* FT_GASP_NO_TABLE ::
* This special value means that there is no GASP table in this face.
* It is up to the client to decide what to do.
*
* FT_GASP_DO_GRIDFIT ::
* Grid-fitting and hinting should be performed at the specified ppem.
* This **really** means TrueType bytecode interpretation. If this bit
* is not set, no hinting gets applied.
*
* FT_GASP_DO_GRAY ::
* Anti-aliased rendering should be performed at the specified ppem.
* If not set, do monochrome rendering.
*
* FT_GASP_SYMMETRIC_SMOOTHING ::
* If set, smoothing along multiple axes must be used with ClearType.
*
* FT_GASP_SYMMETRIC_GRIDFIT ::
* Grid-fitting must be used with ClearType's symmetric smoothing.
*
* @note:
* The bit-flags `FT_GASP_DO_GRIDFIT` and `FT_GASP_DO_GRAY` are to be
* used for standard font rasterization only. Independently of that,
* `FT_GASP_SYMMETRIC_SMOOTHING` and `FT_GASP_SYMMETRIC_GRIDFIT` are to
* be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT` and
* `FT_GASP_DO_GRAY` are consequently ignored).
*
* 'ClearType' is Microsoft's implementation of LCD rendering, partly
* protected by patents.
*
* @since:
* 2.3.0
*/
#define FT_GASP_NO_TABLE -1
#define FT_GASP_DO_GRIDFIT 0x01
#define FT_GASP_DO_GRAY 0x02
#define FT_GASP_SYMMETRIC_GRIDFIT 0x04
#define FT_GASP_SYMMETRIC_SMOOTHING 0x08
/**************************************************************************
*
* @function:
* FT_Get_Gasp
*
* @description:
* For a TrueType or OpenType font file, return the rasterizer behaviour
* flags from the font's 'gasp' table corresponding to a given character
* pixel size.
*
* @input:
* face ::
* The source face handle.
*
* ppem ::
* The vertical character pixel size.
*
* @return:
* Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no
* 'gasp' table in the face.
*
* @note:
* If you want to use the MM functionality of OpenType variation fonts
* (i.e., using @FT_Set_Var_Design_Coordinates and friends), call this
* function **after** setting an instance since the return values can
* change.
*
* @since:
* 2.3.0
*/
FT_EXPORT( FT_Int )
FT_Get_Gasp( FT_Face face,
FT_UInt ppem );
/* */
FT_END_HEADER
#endif /* FTGASP_H_ */
/* END */

View File

@ -1,750 +0,0 @@
/****************************************************************************
*
* ftglyph.h
*
* FreeType convenience functions to handle glyphs (specification).
*
* Copyright (C) 1996-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This file contains the definition of several convenience functions that
* can be used by client applications to easily retrieve glyph bitmaps and
* outlines from a given face.
*
* These functions should be optional if you are writing a font server or
* text layout engine on top of FreeType. However, they are pretty handy
* for many other simple uses of the library.
*
*/
#ifndef FTGLYPH_H_
#define FTGLYPH_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* glyph_management
*
* @title:
* Glyph Management
*
* @abstract:
* Generic interface to manage individual glyph data.
*
* @description:
* This section contains definitions used to manage glyph data through
* generic @FT_Glyph objects. Each of them can contain a bitmap,
* a vector outline, or even images in other formats. These objects are
* detached from @FT_Face, contrary to @FT_GlyphSlot.
*
*/
/* forward declaration to a private type */
typedef struct FT_Glyph_Class_ FT_Glyph_Class;
/**************************************************************************
*
* @type:
* FT_Glyph
*
* @description:
* Handle to an object used to model generic glyph images. It is a
* pointer to the @FT_GlyphRec structure and can contain a glyph bitmap
* or pointer.
*
* @note:
* Glyph objects are not owned by the library. You must thus release
* them manually (through @FT_Done_Glyph) _before_ calling
* @FT_Done_FreeType.
*/
typedef struct FT_GlyphRec_* FT_Glyph;
/**************************************************************************
*
* @struct:
* FT_GlyphRec
*
* @description:
* The root glyph structure contains a given glyph image plus its advance
* width in 16.16 fixed-point format.
*
* @fields:
* library ::
* A handle to the FreeType library object.
*
* clazz ::
* A pointer to the glyph's class. Private.
*
* format ::
* The format of the glyph's image.
*
* advance ::
* A 16.16 vector that gives the glyph's advance width.
*/
typedef struct FT_GlyphRec_
{
FT_Library library;
const FT_Glyph_Class* clazz;
FT_Glyph_Format format;
FT_Vector advance;
} FT_GlyphRec;
/**************************************************************************
*
* @type:
* FT_BitmapGlyph
*
* @description:
* A handle to an object used to model a bitmap glyph image. This is a
* 'sub-class' of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec.
*/
typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph;
/**************************************************************************
*
* @struct:
* FT_BitmapGlyphRec
*
* @description:
* A structure used for bitmap glyph images. This really is a
* 'sub-class' of @FT_GlyphRec.
*
* @fields:
* root ::
* The root fields of @FT_Glyph.
*
* left ::
* The left-side bearing, i.e., the horizontal distance from the
* current pen position to the left border of the glyph bitmap.
*
* top ::
* The top-side bearing, i.e., the vertical distance from the current
* pen position to the top border of the glyph bitmap. This distance
* is positive for upwards~y!
*
* bitmap ::
* A descriptor for the bitmap.
*
* @note:
* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have
* `glyph->format == FT_GLYPH_FORMAT_BITMAP`. This lets you access the
* bitmap's contents easily.
*
* The corresponding pixel buffer is always owned by @FT_BitmapGlyph and
* is thus created and destroyed with it.
*/
typedef struct FT_BitmapGlyphRec_
{
FT_GlyphRec root;
FT_Int left;
FT_Int top;
FT_Bitmap bitmap;
} FT_BitmapGlyphRec;
/**************************************************************************
*
* @type:
* FT_OutlineGlyph
*
* @description:
* A handle to an object used to model an outline glyph image. This is a
* 'sub-class' of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec.
*/
typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph;
/**************************************************************************
*
* @struct:
* FT_OutlineGlyphRec
*
* @description:
* A structure used for outline (vectorial) glyph images. This really is
* a 'sub-class' of @FT_GlyphRec.
*
* @fields:
* root ::
* The root @FT_Glyph fields.
*
* outline ::
* A descriptor for the outline.
*
* @note:
* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have
* `glyph->format == FT_GLYPH_FORMAT_OUTLINE`. This lets you access the
* outline's content easily.
*
* As the outline is extracted from a glyph slot, its coordinates are
* expressed normally in 26.6 pixels, unless the flag @FT_LOAD_NO_SCALE
* was used in @FT_Load_Glyph or @FT_Load_Char.
*
* The outline's tables are always owned by the object and are destroyed
* with it.
*/
typedef struct FT_OutlineGlyphRec_
{
FT_GlyphRec root;
FT_Outline outline;
} FT_OutlineGlyphRec;
/**************************************************************************
*
* @type:
* FT_SvgGlyph
*
* @description:
* A handle to an object used to model an SVG glyph. This is a
* 'sub-class' of @FT_Glyph, and a pointer to @FT_SvgGlyphRec.
*
* @since:
* 2.12
*/
typedef struct FT_SvgGlyphRec_* FT_SvgGlyph;
/**************************************************************************
*
* @struct:
* FT_SvgGlyphRec
*
* @description:
* A structure used for OT-SVG glyphs. This is a 'sub-class' of
* @FT_GlyphRec.
*
* @fields:
* root ::
* The root @FT_GlyphRec fields.
*
* svg_document ::
* A pointer to the SVG document.
*
* svg_document_length ::
* The length of `svg_document`.
*
* glyph_index ::
* The index of the glyph to be rendered.
*
* metrics ::
* A metrics object storing the size information.
*
* units_per_EM ::
* The size of the EM square.
*
* start_glyph_id ::
* The first glyph ID in the glyph range covered by this document.
*
* end_glyph_id ::
* The last glyph ID in the glyph range covered by this document.
*
* transform ::
* A 2x2 transformation matrix to apply to the glyph while rendering
* it.
*
* delta ::
* Translation to apply to the glyph while rendering.
*
* @note:
* The Glyph Management API requires @FT_Glyph or its 'sub-class' to have
* all the information needed to completely define the glyph's rendering.
* Outline-based glyphs can directly apply transformations to the outline
* but this is not possible for an SVG document that hasn't been parsed.
* Therefore, the transformation is stored along with the document. In
* the absence of a 'ViewBox' or 'Width'/'Height' attribute, the size of
* the ViewPort should be assumed to be 'units_per_EM'.
*/
typedef struct FT_SvgGlyphRec_
{
FT_GlyphRec root;
FT_Byte* svg_document;
FT_ULong svg_document_length;
FT_UInt glyph_index;
FT_Size_Metrics metrics;
FT_UShort units_per_EM;
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
FT_Matrix transform;
FT_Vector delta;
} FT_SvgGlyphRec;
/**************************************************************************
*
* @function:
* FT_New_Glyph
*
* @description:
* A function used to create a new empty glyph image. Note that the
* created @FT_Glyph object must be released with @FT_Done_Glyph.
*
* @input:
* library ::
* A handle to the FreeType library object.
*
* format ::
* The format of the glyph's image.
*
* @output:
* aglyph ::
* A handle to the glyph object.
*
* @return:
* FreeType error code. 0~means success.
*
* @since:
* 2.10
*/
FT_EXPORT( FT_Error )
FT_New_Glyph( FT_Library library,
FT_Glyph_Format format,
FT_Glyph *aglyph );
/**************************************************************************
*
* @function:
* FT_Get_Glyph
*
* @description:
* A function used to extract a glyph image from a slot. Note that the
* created @FT_Glyph object must be released with @FT_Done_Glyph.
*
* @input:
* slot ::
* A handle to the source glyph slot.
*
* @output:
* aglyph ::
* A handle to the glyph object.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* Because `*aglyph->advance.x` and `*aglyph->advance.y` are 16.16
* fixed-point numbers, `slot->advance.x` and `slot->advance.y` (which
* are in 26.6 fixed-point format) must be in the range ]-32768;32768[.
*/
FT_EXPORT( FT_Error )
FT_Get_Glyph( FT_GlyphSlot slot,
FT_Glyph *aglyph );
/**************************************************************************
*
* @function:
* FT_Glyph_Copy
*
* @description:
* A function used to copy a glyph image. Note that the created
* @FT_Glyph object must be released with @FT_Done_Glyph.
*
* @input:
* source ::
* A handle to the source glyph object.
*
* @output:
* target ::
* A handle to the target glyph object. 0~in case of error.
*
* @return:
* FreeType error code. 0~means success.
*/
FT_EXPORT( FT_Error )
FT_Glyph_Copy( FT_Glyph source,
FT_Glyph *target );
/**************************************************************************
*
* @function:
* FT_Glyph_Transform
*
* @description:
* Transform a glyph image if its format is scalable.
*
* @inout:
* glyph ::
* A handle to the target glyph object.
*
* @input:
* matrix ::
* A pointer to a 2x2 matrix to apply.
*
* delta ::
* A pointer to a 2d vector to apply. Coordinates are expressed in
* 1/64th of a pixel.
*
* @return:
* FreeType error code (if not 0, the glyph format is not scalable).
*
* @note:
* The 2x2 transformation matrix is also applied to the glyph's advance
* vector.
*/
FT_EXPORT( FT_Error )
FT_Glyph_Transform( FT_Glyph glyph,
const FT_Matrix* matrix,
const FT_Vector* delta );
/**************************************************************************
*
* @enum:
* FT_Glyph_BBox_Mode
*
* @description:
* The mode how the values of @FT_Glyph_Get_CBox are returned.
*
* @values:
* FT_GLYPH_BBOX_UNSCALED ::
* Return unscaled font units.
*
* FT_GLYPH_BBOX_SUBPIXELS ::
* Return unfitted 26.6 coordinates.
*
* FT_GLYPH_BBOX_GRIDFIT ::
* Return grid-fitted 26.6 coordinates.
*
* FT_GLYPH_BBOX_TRUNCATE ::
* Return coordinates in integer pixels.
*
* FT_GLYPH_BBOX_PIXELS ::
* Return grid-fitted pixel coordinates.
*/
typedef enum FT_Glyph_BBox_Mode_
{
FT_GLYPH_BBOX_UNSCALED = 0,
FT_GLYPH_BBOX_SUBPIXELS = 0,
FT_GLYPH_BBOX_GRIDFIT = 1,
FT_GLYPH_BBOX_TRUNCATE = 2,
FT_GLYPH_BBOX_PIXELS = 3
} FT_Glyph_BBox_Mode;
/* these constants are deprecated; use the corresponding */
/* `FT_Glyph_BBox_Mode` values instead */
#define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED
#define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS
#define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT
#define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE
#define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS
/**************************************************************************
*
* @function:
* FT_Glyph_Get_CBox
*
* @description:
* Return a glyph's 'control box'. The control box encloses all the
* outline's points, including Bezier control points. Though it
* coincides with the exact bounding box for most glyphs, it can be
* slightly larger in some situations (like when rotating an outline that
* contains Bezier outside arcs).
*
* Computing the control box is very fast, while getting the bounding box
* can take much more time as it needs to walk over all segments and arcs
* in the outline. To get the latter, you can use the 'ftbbox'
* component, which is dedicated to this single task.
*
* @input:
* glyph ::
* A handle to the source glyph object.
*
* mode ::
* The mode that indicates how to interpret the returned bounding box
* values.
*
* @output:
* acbox ::
* The glyph coordinate bounding box. Coordinates are expressed in
* 1/64th of pixels if it is grid-fitted.
*
* @note:
* Coordinates are relative to the glyph origin, using the y~upwards
* convention.
*
* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode` must
* be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font units in 26.6
* pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS is another name for
* this constant.
*
* If the font is tricky and the glyph has been loaded with
* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get
* reasonable values for the CBox it is necessary to load the glyph at a
* large ppem value (so that the hinting instructions can properly shift
* and scale the subglyphs), then extracting the CBox, which can be
* eventually converted back to font units.
*
* Note that the maximum coordinates are exclusive, which means that one
* can compute the width and height of the glyph image (be it in integer
* or 26.6 pixels) as:
*
* ```
* width = bbox.xMax - bbox.xMin;
* height = bbox.yMax - bbox.yMin;
* ```
*
* Note also that for 26.6 coordinates, if `bbox_mode` is set to
* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted,
* which corresponds to:
*
* ```
* bbox.xMin = FLOOR(bbox.xMin);
* bbox.yMin = FLOOR(bbox.yMin);
* bbox.xMax = CEILING(bbox.xMax);
* bbox.yMax = CEILING(bbox.yMax);
* ```
*
* To get the bbox in pixel coordinates, set `bbox_mode` to
* @FT_GLYPH_BBOX_TRUNCATE.
*
* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode` to
* @FT_GLYPH_BBOX_PIXELS.
*/
FT_EXPORT( void )
FT_Glyph_Get_CBox( FT_Glyph glyph,
FT_UInt bbox_mode,
FT_BBox *acbox );
/**************************************************************************
*
* @function:
* FT_Glyph_To_Bitmap
*
* @description:
* Convert a given glyph object to a bitmap glyph object.
*
* @inout:
* the_glyph ::
* A pointer to a handle to the target glyph.
*
* @input:
* render_mode ::
* An enumeration that describes how the data is rendered.
*
* origin ::
* A pointer to a vector used to translate the glyph image before
* rendering. Can be~0 (if no translation). The origin is expressed
* in 26.6 pixels.
*
* destroy ::
* A boolean that indicates that the original glyph image should be
* destroyed by this function. It is never destroyed in case of error.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function does nothing if the glyph format isn't scalable.
*
* The glyph image is translated with the `origin` vector before
* rendering.
*
* The first parameter is a pointer to an @FT_Glyph handle that will be
* _replaced_ by this function (with newly allocated data). Typically,
* you would do something like the following (omitting error handling).
*
* ```
* FT_Glyph glyph;
* FT_BitmapGlyph glyph_bitmap;
*
*
* // load glyph
* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAULT );
*
* // extract glyph image
* error = FT_Get_Glyph( face->glyph, &glyph );
*
* // convert to a bitmap (default render mode + destroying old)
* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
* {
* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL,
* 0, 1 );
* if ( error ) // `glyph' unchanged
* ...
* }
*
* // access bitmap content by typecasting
* glyph_bitmap = (FT_BitmapGlyph)glyph;
*
* // do funny stuff with it, like blitting/drawing
* ...
*
* // discard glyph image (bitmap or not)
* FT_Done_Glyph( glyph );
* ```
*
* Here is another example, again without error handling.
*
* ```
* FT_Glyph glyphs[MAX_GLYPHS]
*
*
* ...
*
* for ( idx = 0; i < MAX_GLYPHS; i++ )
* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) ||
* FT_Get_Glyph ( face->glyph, &glyphs[idx] );
*
* ...
*
* for ( idx = 0; i < MAX_GLYPHS; i++ )
* {
* FT_Glyph bitmap = glyphs[idx];
*
*
* ...
*
* // after this call, `bitmap' no longer points into
* // the `glyphs' array (and the old value isn't destroyed)
* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 );
*
* ...
*
* FT_Done_Glyph( bitmap );
* }
*
* ...
*
* for ( idx = 0; i < MAX_GLYPHS; i++ )
* FT_Done_Glyph( glyphs[idx] );
* ```
*/
FT_EXPORT( FT_Error )
FT_Glyph_To_Bitmap( FT_Glyph* the_glyph,
FT_Render_Mode render_mode,
const FT_Vector* origin,
FT_Bool destroy );
/**************************************************************************
*
* @function:
* FT_Done_Glyph
*
* @description:
* Destroy a given glyph.
*
* @input:
* glyph ::
* A handle to the target glyph object.
*/
FT_EXPORT( void )
FT_Done_Glyph( FT_Glyph glyph );
/* */
/* other helpful functions */
/**************************************************************************
*
* @section:
* computations
*
*/
/**************************************************************************
*
* @function:
* FT_Matrix_Multiply
*
* @description:
* Perform the matrix operation `b = a*b`.
*
* @input:
* a ::
* A pointer to matrix `a`.
*
* @inout:
* b ::
* A pointer to matrix `b`.
*
* @note:
* The result is undefined if either `a` or `b` is zero.
*
* Since the function uses wrap-around arithmetic, results become
* meaningless if the arguments are very large.
*/
FT_EXPORT( void )
FT_Matrix_Multiply( const FT_Matrix* a,
FT_Matrix* b );
/**************************************************************************
*
* @function:
* FT_Matrix_Invert
*
* @description:
* Invert a 2x2 matrix. Return an error if it can't be inverted.
*
* @inout:
* matrix ::
* A pointer to the target matrix. Remains untouched in case of error.
*
* @return:
* FreeType error code. 0~means success.
*/
FT_EXPORT( FT_Error )
FT_Matrix_Invert( FT_Matrix* matrix );
/* */
FT_END_HEADER
#endif /* FTGLYPH_H_ */
/* END */
/* Local Variables: */
/* coding: utf-8 */
/* End: */

View File

@ -1,354 +0,0 @@
/****************************************************************************
*
* ftgxval.h
*
* FreeType API for validating TrueTypeGX/AAT tables (specification).
*
* Copyright (C) 2004-2022 by
* Masatake YAMATO, Redhat K.K,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/****************************************************************************
*
* gxvalid is derived from both gxlayout module and otvalid module.
* Development of gxlayout is supported by the Information-technology
* Promotion Agency(IPA), Japan.
*
*/
#ifndef FTGXVAL_H_
#define FTGXVAL_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* gx_validation
*
* @title:
* TrueTypeGX/AAT Validation
*
* @abstract:
* An API to validate TrueTypeGX/AAT tables.
*
* @description:
* This section contains the declaration of functions to validate some
* TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, trak,
* prop, lcar).
*
* @order:
* FT_TrueTypeGX_Validate
* FT_TrueTypeGX_Free
*
* FT_ClassicKern_Validate
* FT_ClassicKern_Free
*
* FT_VALIDATE_GX_LENGTH
* FT_VALIDATE_GXXXX
* FT_VALIDATE_CKERNXXX
*
*/
/**************************************************************************
*
*
* Warning: Use `FT_VALIDATE_XXX` to validate a table.
* Following definitions are for gxvalid developers.
*
*
*/
#define FT_VALIDATE_feat_INDEX 0
#define FT_VALIDATE_mort_INDEX 1
#define FT_VALIDATE_morx_INDEX 2
#define FT_VALIDATE_bsln_INDEX 3
#define FT_VALIDATE_just_INDEX 4
#define FT_VALIDATE_kern_INDEX 5
#define FT_VALIDATE_opbd_INDEX 6
#define FT_VALIDATE_trak_INDEX 7
#define FT_VALIDATE_prop_INDEX 8
#define FT_VALIDATE_lcar_INDEX 9
#define FT_VALIDATE_GX_LAST_INDEX FT_VALIDATE_lcar_INDEX
/**************************************************************************
*
* @macro:
* FT_VALIDATE_GX_LENGTH
*
* @description:
* The number of tables checked in this module. Use it as a parameter
* for the `table-length` argument of function @FT_TrueTypeGX_Validate.
*/
#define FT_VALIDATE_GX_LENGTH ( FT_VALIDATE_GX_LAST_INDEX + 1 )
/* */
/* Up to 0x1000 is used by otvalid.
Ox2xxx is reserved for feature OT extension. */
#define FT_VALIDATE_GX_START 0x4000
#define FT_VALIDATE_GX_BITFIELD( tag ) \
( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX )
/**************************************************************************
*
* @enum:
* FT_VALIDATE_GXXXX
*
* @description:
* A list of bit-field constants used with @FT_TrueTypeGX_Validate to
* indicate which TrueTypeGX/AAT Type tables should be validated.
*
* @values:
* FT_VALIDATE_feat ::
* Validate 'feat' table.
*
* FT_VALIDATE_mort ::
* Validate 'mort' table.
*
* FT_VALIDATE_morx ::
* Validate 'morx' table.
*
* FT_VALIDATE_bsln ::
* Validate 'bsln' table.
*
* FT_VALIDATE_just ::
* Validate 'just' table.
*
* FT_VALIDATE_kern ::
* Validate 'kern' table.
*
* FT_VALIDATE_opbd ::
* Validate 'opbd' table.
*
* FT_VALIDATE_trak ::
* Validate 'trak' table.
*
* FT_VALIDATE_prop ::
* Validate 'prop' table.
*
* FT_VALIDATE_lcar ::
* Validate 'lcar' table.
*
* FT_VALIDATE_GX ::
* Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern,
* opbd, trak, prop and lcar).
*
*/
#define FT_VALIDATE_feat FT_VALIDATE_GX_BITFIELD( feat )
#define FT_VALIDATE_mort FT_VALIDATE_GX_BITFIELD( mort )
#define FT_VALIDATE_morx FT_VALIDATE_GX_BITFIELD( morx )
#define FT_VALIDATE_bsln FT_VALIDATE_GX_BITFIELD( bsln )
#define FT_VALIDATE_just FT_VALIDATE_GX_BITFIELD( just )
#define FT_VALIDATE_kern FT_VALIDATE_GX_BITFIELD( kern )
#define FT_VALIDATE_opbd FT_VALIDATE_GX_BITFIELD( opbd )
#define FT_VALIDATE_trak FT_VALIDATE_GX_BITFIELD( trak )
#define FT_VALIDATE_prop FT_VALIDATE_GX_BITFIELD( prop )
#define FT_VALIDATE_lcar FT_VALIDATE_GX_BITFIELD( lcar )
#define FT_VALIDATE_GX ( FT_VALIDATE_feat | \
FT_VALIDATE_mort | \
FT_VALIDATE_morx | \
FT_VALIDATE_bsln | \
FT_VALIDATE_just | \
FT_VALIDATE_kern | \
FT_VALIDATE_opbd | \
FT_VALIDATE_trak | \
FT_VALIDATE_prop | \
FT_VALIDATE_lcar )
/**************************************************************************
*
* @function:
* FT_TrueTypeGX_Validate
*
* @description:
* Validate various TrueTypeGX tables to assure that all offsets and
* indices are valid. The idea is that a higher-level library that
* actually does the text layout can access those tables without error
* checking (which can be quite time consuming).
*
* @input:
* face ::
* A handle to the input face.
*
* validation_flags ::
* A bit field that specifies the tables to be validated. See
* @FT_VALIDATE_GXXXX for possible values.
*
* table_length ::
* The size of the `tables` array. Normally, @FT_VALIDATE_GX_LENGTH
* should be passed.
*
* @output:
* tables ::
* The array where all validated sfnt tables are stored. The array
* itself must be allocated by a client.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function only works with TrueTypeGX fonts, returning an error
* otherwise.
*
* After use, the application should deallocate the buffers pointed to by
* each `tables` element, by calling @FT_TrueTypeGX_Free. A `NULL` value
* indicates that the table either doesn't exist in the font, the
* application hasn't asked for validation, or the validator doesn't have
* the ability to validate the sfnt table.
*/
FT_EXPORT( FT_Error )
FT_TrueTypeGX_Validate( FT_Face face,
FT_UInt validation_flags,
FT_Bytes tables[FT_VALIDATE_GX_LENGTH],
FT_UInt table_length );
/**************************************************************************
*
* @function:
* FT_TrueTypeGX_Free
*
* @description:
* Free the buffer allocated by TrueTypeGX validator.
*
* @input:
* face ::
* A handle to the input face.
*
* table ::
* The pointer to the buffer allocated by @FT_TrueTypeGX_Validate.
*
* @note:
* This function must be used to free the buffer allocated by
* @FT_TrueTypeGX_Validate only.
*/
FT_EXPORT( void )
FT_TrueTypeGX_Free( FT_Face face,
FT_Bytes table );
/**************************************************************************
*
* @enum:
* FT_VALIDATE_CKERNXXX
*
* @description:
* A list of bit-field constants used with @FT_ClassicKern_Validate to
* indicate the classic kern dialect or dialects. If the selected type
* doesn't fit, @FT_ClassicKern_Validate regards the table as invalid.
*
* @values:
* FT_VALIDATE_MS ::
* Handle the 'kern' table as a classic Microsoft kern table.
*
* FT_VALIDATE_APPLE ::
* Handle the 'kern' table as a classic Apple kern table.
*
* FT_VALIDATE_CKERN ::
* Handle the 'kern' as either classic Apple or Microsoft kern table.
*/
#define FT_VALIDATE_MS ( FT_VALIDATE_GX_START << 0 )
#define FT_VALIDATE_APPLE ( FT_VALIDATE_GX_START << 1 )
#define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE )
/**************************************************************************
*
* @function:
* FT_ClassicKern_Validate
*
* @description:
* Validate classic (16-bit format) kern table to assure that the
* offsets and indices are valid. The idea is that a higher-level
* library that actually does the text layout can access those tables
* without error checking (which can be quite time consuming).
*
* The 'kern' table validator in @FT_TrueTypeGX_Validate deals with both
* the new 32-bit format and the classic 16-bit format, while
* FT_ClassicKern_Validate only supports the classic 16-bit format.
*
* @input:
* face ::
* A handle to the input face.
*
* validation_flags ::
* A bit field that specifies the dialect to be validated. See
* @FT_VALIDATE_CKERNXXX for possible values.
*
* @output:
* ckern_table ::
* A pointer to the kern table.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* After use, the application should deallocate the buffers pointed to by
* `ckern_table`, by calling @FT_ClassicKern_Free. A `NULL` value
* indicates that the table doesn't exist in the font.
*/
FT_EXPORT( FT_Error )
FT_ClassicKern_Validate( FT_Face face,
FT_UInt validation_flags,
FT_Bytes *ckern_table );
/**************************************************************************
*
* @function:
* FT_ClassicKern_Free
*
* @description:
* Free the buffer allocated by classic Kern validator.
*
* @input:
* face ::
* A handle to the input face.
*
* table ::
* The pointer to the buffer that is allocated by
* @FT_ClassicKern_Validate.
*
* @note:
* This function must be used to free the buffer allocated by
* @FT_ClassicKern_Validate only.
*/
FT_EXPORT( void )
FT_ClassicKern_Free( FT_Face face,
FT_Bytes table );
/* */
FT_END_HEADER
#endif /* FTGXVAL_H_ */
/* END */

View File

@ -1,151 +0,0 @@
/****************************************************************************
*
* ftgzip.h
*
* Gzip-compressed stream support.
*
* Copyright (C) 2002-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTGZIP_H_
#define FTGZIP_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* gzip
*
* @title:
* GZIP Streams
*
* @abstract:
* Using gzip-compressed font files.
*
* @description:
* In certain builds of the library, gzip compression recognition is
* automatically handled when calling @FT_New_Face or @FT_Open_Face.
* This means that if no font driver is capable of handling the raw
* compressed file, the library will try to open a gzipped stream from it
* and re-open the face with it.
*
* The stream implementation is very basic and resets the decompression
* process each time seeking backwards is needed within the stream,
* which significantly undermines the performance.
*
* This section contains the declaration of Gzip-specific functions.
*
*/
/**************************************************************************
*
* @function:
* FT_Stream_OpenGzip
*
* @description:
* Open a new stream to parse gzip-compressed font files. This is mainly
* used to support the compressed `*.pcf.gz` fonts that come with
* XFree86.
*
* @input:
* stream ::
* The target embedding stream.
*
* source ::
* The source stream.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The source stream must be opened _before_ calling this function.
*
* Calling the internal function `FT_Stream_Close` on the new stream will
* **not** call `FT_Stream_Close` on the source stream. None of the
* stream objects will be released to the heap.
*
* This function may return `FT_Err_Unimplemented_Feature` if your build
* of FreeType was not compiled with zlib support.
*/
FT_EXPORT( FT_Error )
FT_Stream_OpenGzip( FT_Stream stream,
FT_Stream source );
/**************************************************************************
*
* @function:
* FT_Gzip_Uncompress
*
* @description:
* Decompress a zipped input buffer into an output buffer. This function
* is modeled after zlib's `uncompress` function.
*
* @input:
* memory ::
* A FreeType memory handle.
*
* input ::
* The input buffer.
*
* input_len ::
* The length of the input buffer.
*
* @output:
* output ::
* The output buffer.
*
* @inout:
* output_len ::
* Before calling the function, this is the total size of the output
* buffer, which must be large enough to hold the entire uncompressed
* data (so the size of the uncompressed data must be known in
* advance). After calling the function, `output_len` is the size of
* the used data in `output`.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function may return `FT_Err_Unimplemented_Feature` if your build
* of FreeType was not compiled with zlib support.
*
* @since:
* 2.5.1
*/
FT_EXPORT( FT_Error )
FT_Gzip_Uncompress( FT_Memory memory,
FT_Byte* output,
FT_ULong* output_len,
const FT_Byte* input,
FT_ULong input_len );
/* */
FT_END_HEADER
#endif /* FTGZIP_H_ */
/* END */

File diff suppressed because it is too large Load Diff

View File

@ -1,348 +0,0 @@
/****************************************************************************
*
* ftincrem.h
*
* FreeType incremental loading (specification).
*
* Copyright (C) 2002-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTINCREM_H_
#define FTINCREM_H_
#include <freetype/freetype.h>
#include <freetype/ftparams.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* incremental
*
* @title:
* Incremental Loading
*
* @abstract:
* Custom Glyph Loading.
*
* @description:
* This section contains various functions used to perform so-called
* 'incremental' glyph loading. This is a mode where all glyphs loaded
* from a given @FT_Face are provided by the client application.
*
* Apart from that, all other tables are loaded normally from the font
* file. This mode is useful when FreeType is used within another
* engine, e.g., a PostScript Imaging Processor.
*
* To enable this mode, you must use @FT_Open_Face, passing an
* @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an
* @FT_Incremental_Interface value. See the comments for
* @FT_Incremental_InterfaceRec for an example.
*
*/
/**************************************************************************
*
* @type:
* FT_Incremental
*
* @description:
* An opaque type describing a user-provided object used to implement
* 'incremental' glyph loading within FreeType. This is used to support
* embedded fonts in certain environments (e.g., PostScript
* interpreters), where the glyph data isn't in the font file, or must be
* overridden by different values.
*
* @note:
* It is up to client applications to create and implement
* @FT_Incremental objects, as long as they provide implementations for
* the methods @FT_Incremental_GetGlyphDataFunc,
* @FT_Incremental_FreeGlyphDataFunc and
* @FT_Incremental_GetGlyphMetricsFunc.
*
* See the description of @FT_Incremental_InterfaceRec to understand how
* to use incremental objects with FreeType.
*
*/
typedef struct FT_IncrementalRec_* FT_Incremental;
/**************************************************************************
*
* @struct:
* FT_Incremental_MetricsRec
*
* @description:
* A small structure used to contain the basic glyph metrics returned by
* the @FT_Incremental_GetGlyphMetricsFunc method.
*
* @fields:
* bearing_x ::
* Left bearing, in font units.
*
* bearing_y ::
* Top bearing, in font units.
*
* advance ::
* Horizontal component of glyph advance, in font units.
*
* advance_v ::
* Vertical component of glyph advance, in font units.
*
* @note:
* These correspond to horizontal or vertical metrics depending on the
* value of the `vertical` argument to the function
* @FT_Incremental_GetGlyphMetricsFunc.
*
*/
typedef struct FT_Incremental_MetricsRec_
{
FT_Long bearing_x;
FT_Long bearing_y;
FT_Long advance;
FT_Long advance_v; /* since 2.3.12 */
} FT_Incremental_MetricsRec;
/**************************************************************************
*
* @struct:
* FT_Incremental_Metrics
*
* @description:
* A handle to an @FT_Incremental_MetricsRec structure.
*
*/
typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics;
/**************************************************************************
*
* @type:
* FT_Incremental_GetGlyphDataFunc
*
* @description:
* A function called by FreeType to access a given glyph's data bytes
* during @FT_Load_Glyph or @FT_Load_Char if incremental loading is
* enabled.
*
* Note that the format of the glyph's data bytes depends on the font
* file format. For TrueType, it must correspond to the raw bytes within
* the 'glyf' table. For PostScript formats, it must correspond to the
* **unencrypted** charstring bytes, without any `lenIV` header. It is
* undefined for any other format.
*
* @input:
* incremental ::
* Handle to an opaque @FT_Incremental handle provided by the client
* application.
*
* glyph_index ::
* Index of relevant glyph.
*
* @output:
* adata ::
* A structure describing the returned glyph data bytes (which will be
* accessed as a read-only byte block).
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* If this function returns successfully the method
* @FT_Incremental_FreeGlyphDataFunc will be called later to release the
* data bytes.
*
* Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for
* compound glyphs.
*
*/
typedef FT_Error
(*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental,
FT_UInt glyph_index,
FT_Data* adata );
/**************************************************************************
*
* @type:
* FT_Incremental_FreeGlyphDataFunc
*
* @description:
* A function used to release the glyph data bytes returned by a
* successful call to @FT_Incremental_GetGlyphDataFunc.
*
* @input:
* incremental ::
* A handle to an opaque @FT_Incremental handle provided by the client
* application.
*
* data ::
* A structure describing the glyph data bytes (which will be accessed
* as a read-only byte block).
*
*/
typedef void
(*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental,
FT_Data* data );
/**************************************************************************
*
* @type:
* FT_Incremental_GetGlyphMetricsFunc
*
* @description:
* A function used to retrieve the basic metrics of a given glyph index
* before accessing its data. This allows for handling font types such
* as PCL~XL Format~1, Class~2 downloaded TrueType fonts, where the glyph
* metrics (`hmtx` and `vmtx` tables) are permitted to be omitted from
* the font, and the relevant metrics included in the header of the glyph
* outline data. Importantly, this is not intended to allow custom glyph
* metrics (for example, Postscript Metrics dictionaries), because that
* conflicts with the requirements of outline hinting. Such custom
* metrics must be handled separately, by the calling application.
*
* @input:
* incremental ::
* A handle to an opaque @FT_Incremental handle provided by the client
* application.
*
* glyph_index ::
* Index of relevant glyph.
*
* vertical ::
* If true, return vertical metrics.
*
* ametrics ::
* This parameter is used for both input and output. The original
* glyph metrics, if any, in font units. If metrics are not available
* all the values must be set to zero.
*
* @output:
* ametrics ::
* The glyph metrics in font units.
*
*/
typedef FT_Error
(*FT_Incremental_GetGlyphMetricsFunc)
( FT_Incremental incremental,
FT_UInt glyph_index,
FT_Bool vertical,
FT_Incremental_MetricsRec *ametrics );
/**************************************************************************
*
* @struct:
* FT_Incremental_FuncsRec
*
* @description:
* A table of functions for accessing fonts that load data incrementally.
* Used in @FT_Incremental_InterfaceRec.
*
* @fields:
* get_glyph_data ::
* The function to get glyph data. Must not be null.
*
* free_glyph_data ::
* The function to release glyph data. Must not be null.
*
* get_glyph_metrics ::
* The function to get glyph metrics. May be null if the font does not
* require it.
*
*/
typedef struct FT_Incremental_FuncsRec_
{
FT_Incremental_GetGlyphDataFunc get_glyph_data;
FT_Incremental_FreeGlyphDataFunc free_glyph_data;
FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics;
} FT_Incremental_FuncsRec;
/**************************************************************************
*
* @struct:
* FT_Incremental_InterfaceRec
*
* @description:
* A structure to be used with @FT_Open_Face to indicate that the user
* wants to support incremental glyph loading. You should use it with
* @FT_PARAM_TAG_INCREMENTAL as in the following example:
*
* ```
* FT_Incremental_InterfaceRec inc_int;
* FT_Parameter parameter;
* FT_Open_Args open_args;
*
*
* // set up incremental descriptor
* inc_int.funcs = my_funcs;
* inc_int.object = my_object;
*
* // set up optional parameter
* parameter.tag = FT_PARAM_TAG_INCREMENTAL;
* parameter.data = &inc_int;
*
* // set up FT_Open_Args structure
* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;
* open_args.pathname = my_font_pathname;
* open_args.num_params = 1;
* open_args.params = &parameter; // we use one optional argument
*
* // open the font
* error = FT_Open_Face( library, &open_args, index, &face );
* ...
* ```
*
*/
typedef struct FT_Incremental_InterfaceRec_
{
const FT_Incremental_FuncsRec* funcs;
FT_Incremental object;
} FT_Incremental_InterfaceRec;
/**************************************************************************
*
* @type:
* FT_Incremental_Interface
*
* @description:
* A pointer to an @FT_Incremental_InterfaceRec structure.
*
*/
typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface;
/* */
FT_END_HEADER
#endif /* FTINCREM_H_ */
/* END */

View File

@ -1,323 +0,0 @@
/****************************************************************************
*
* ftlcdfil.h
*
* FreeType API for color filtering of subpixel bitmap glyphs
* (specification).
*
* Copyright (C) 2006-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTLCDFIL_H_
#define FTLCDFIL_H_
#include <freetype/freetype.h>
#include <freetype/ftparams.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* lcd_rendering
*
* @title:
* Subpixel Rendering
*
* @abstract:
* API to control subpixel rendering.
*
* @description:
* FreeType provides two alternative subpixel rendering technologies.
* Should you define `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` in your
* `ftoption.h` file, this enables ClearType-style rendering.
* Otherwise, Harmony LCD rendering is enabled. These technologies are
* controlled differently and API described below, although always
* available, performs its function when appropriate method is enabled
* and does nothing otherwise.
*
* ClearType-style LCD rendering exploits the color-striped structure of
* LCD pixels, increasing the available resolution in the direction of
* the stripe (usually horizontal RGB) by a factor of~3. Using the
* subpixel coverages unfiltered can create severe color fringes
* especially when rendering thin features. Indeed, to produce
* black-on-white text, the nearby color subpixels must be dimmed
* evenly. Therefore, an equalizing 5-tap FIR filter should be applied
* to subpixel coverages regardless of pixel boundaries and should have
* these properties:
*
* 1. It should be symmetrical, like {~a, b, c, b, a~}, to avoid
* any shifts in appearance.
*
* 2. It should be color-balanced, meaning a~+ b~=~c, to reduce color
* fringes by distributing the computed coverage for one subpixel to
* all subpixels equally.
*
* 3. It should be normalized, meaning 2a~+ 2b~+ c~=~1.0 to maintain
* overall brightness.
*
* Boxy 3-tap filter {0, 1/3, 1/3, 1/3, 0} is sharper but is less
* forgiving of non-ideal gamma curves of a screen (and viewing angles),
* beveled filters are fuzzier but more tolerant.
*
* Use the @FT_Library_SetLcdFilter or @FT_Library_SetLcdFilterWeights
* API to specify a low-pass filter, which is then applied to
* subpixel-rendered bitmaps generated through @FT_Render_Glyph.
*
* Harmony LCD rendering is suitable to panels with any regular subpixel
* structure, not just monitors with 3 color striped subpixels, as long
* as the color subpixels have fixed positions relative to the pixel
* center. In this case, each color channel can be rendered separately
* after shifting the outline opposite to the subpixel shift so that the
* coverage maps are aligned. This method is immune to color fringes
* because the shifts do not change integral coverage.
*
* The subpixel geometry must be specified by xy-coordinates for each
* subpixel. By convention they may come in the RGB order: {{-1/3, 0},
* {0, 0}, {1/3, 0}} for standard RGB striped panel or {{-1/6, 1/4},
* {-1/6, -1/4}, {1/3, 0}} for a certain PenTile panel.
*
* Use the @FT_Library_SetLcdGeometry API to specify subpixel positions.
* If one follows the RGB order convention, the same order applies to the
* resulting @FT_PIXEL_MODE_LCD and @FT_PIXEL_MODE_LCD_V bitmaps. Note,
* however, that the coordinate frame for the latter must be rotated
* clockwise. Harmony with default LCD geometry is equivalent to
* ClearType with light filter.
*
* As a result of ClearType filtering or Harmony shifts, the resulting
* dimensions of LCD bitmaps can be slightly wider or taller than the
* dimensions the original outline with regard to the pixel grid.
* For example, for @FT_RENDER_MODE_LCD, the filter adds 2~subpixels to
* the left, and 2~subpixels to the right. The bitmap offset values are
* adjusted accordingly, so clients shouldn't need to modify their layout
* and glyph positioning code when enabling the filter.
*
* The ClearType and Harmony rendering is applicable to glyph bitmaps
* rendered through @FT_Render_Glyph, @FT_Load_Glyph, @FT_Load_Char, and
* @FT_Glyph_To_Bitmap, when @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V
* is specified. This API does not control @FT_Outline_Render and
* @FT_Outline_Get_Bitmap.
*
* The described algorithms can completely remove color artefacts when
* combined with gamma-corrected alpha blending in linear space. Each of
* the 3~alpha values (subpixels) must by independently used to blend one
* color channel. That is, red alpha blends the red channel of the text
* color with the red channel of the background pixel.
*/
/**************************************************************************
*
* @enum:
* FT_LcdFilter
*
* @description:
* A list of values to identify various types of LCD filters.
*
* @values:
* FT_LCD_FILTER_NONE ::
* Do not perform filtering. When used with subpixel rendering, this
* results in sometimes severe color fringes.
*
* FT_LCD_FILTER_DEFAULT ::
* This is a beveled, normalized, and color-balanced five-tap filter
* with weights of [0x08 0x4D 0x56 0x4D 0x08] in 1/256th units.
*
* FT_LCD_FILTER_LIGHT ::
* this is a boxy, normalized, and color-balanced three-tap filter with
* weights of [0x00 0x55 0x56 0x55 0x00] in 1/256th units.
*
* FT_LCD_FILTER_LEGACY ::
* FT_LCD_FILTER_LEGACY1 ::
* This filter corresponds to the original libXft color filter. It
* provides high contrast output but can exhibit really bad color
* fringes if glyphs are not extremely well hinted to the pixel grid.
* This filter is only provided for comparison purposes, and might be
* disabled or stay unsupported in the future. The second value is
* provided for compatibility with FontConfig, which historically used
* different enumeration, sometimes incorrectly forwarded to FreeType.
*
* @since:
* 2.3.0 (`FT_LCD_FILTER_LEGACY1` since 2.6.2)
*/
typedef enum FT_LcdFilter_
{
FT_LCD_FILTER_NONE = 0,
FT_LCD_FILTER_DEFAULT = 1,
FT_LCD_FILTER_LIGHT = 2,
FT_LCD_FILTER_LEGACY1 = 3,
FT_LCD_FILTER_LEGACY = 16,
FT_LCD_FILTER_MAX /* do not remove */
} FT_LcdFilter;
/**************************************************************************
*
* @function:
* FT_Library_SetLcdFilter
*
* @description:
* This function is used to change filter applied to LCD decimated
* bitmaps, like the ones used when calling @FT_Render_Glyph with
* @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V.
*
* @input:
* library ::
* A handle to the target library instance.
*
* filter ::
* The filter type.
*
* You can use @FT_LCD_FILTER_NONE here to disable this feature, or
* @FT_LCD_FILTER_DEFAULT to use a default filter that should work well
* on most LCD screens.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* Since 2.10.3 the LCD filtering is enabled with @FT_LCD_FILTER_DEFAULT.
* It is no longer necessary to call this function explicitly except
* to choose a different filter or disable filtering altogether with
* @FT_LCD_FILTER_NONE.
*
* This function does nothing but returns `FT_Err_Unimplemented_Feature`
* if the configuration macro `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is
* not defined in your build of the library.
*
* @since:
* 2.3.0
*/
FT_EXPORT( FT_Error )
FT_Library_SetLcdFilter( FT_Library library,
FT_LcdFilter filter );
/**************************************************************************
*
* @function:
* FT_Library_SetLcdFilterWeights
*
* @description:
* This function can be used to enable LCD filter with custom weights,
* instead of using presets in @FT_Library_SetLcdFilter.
*
* @input:
* library ::
* A handle to the target library instance.
*
* weights ::
* A pointer to an array; the function copies the first five bytes and
* uses them to specify the filter weights in 1/256th units.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function does nothing but returns `FT_Err_Unimplemented_Feature`
* if the configuration macro `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is
* not defined in your build of the library.
*
* LCD filter weights can also be set per face using @FT_Face_Properties
* with @FT_PARAM_TAG_LCD_FILTER_WEIGHTS.
*
* @since:
* 2.4.0
*/
FT_EXPORT( FT_Error )
FT_Library_SetLcdFilterWeights( FT_Library library,
unsigned char *weights );
/**************************************************************************
*
* @type:
* FT_LcdFiveTapFilter
*
* @description:
* A typedef for passing the five LCD filter weights to
* @FT_Face_Properties within an @FT_Parameter structure.
*
* @since:
* 2.8
*
*/
#define FT_LCD_FILTER_FIVE_TAPS 5
typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS];
/**************************************************************************
*
* @function:
* FT_Library_SetLcdGeometry
*
* @description:
* This function can be used to modify default positions of color
* subpixels, which controls Harmony LCD rendering.
*
* @input:
* library ::
* A handle to the target library instance.
*
* sub ::
* A pointer to an array of 3 vectors in 26.6 fractional pixel format;
* the function modifies the default values, see the note below.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* Subpixel geometry examples:
*
* - {{-21, 0}, {0, 0}, {21, 0}} is the default, corresponding to 3 color
* stripes shifted by a third of a pixel. This could be an RGB panel.
*
* - {{21, 0}, {0, 0}, {-21, 0}} looks the same as the default but can
* specify a BGR panel instead, while keeping the bitmap in the same
* RGB888 format.
*
* - {{0, 21}, {0, 0}, {0, -21}} is the vertical RGB, but the bitmap
* stays RGB888 as a result.
*
* - {{-11, 16}, {-11, -16}, {22, 0}} is a certain PenTile arrangement.
*
* This function does nothing and returns `FT_Err_Unimplemented_Feature`
* in the context of ClearType-style subpixel rendering when
* `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is defined in your build of the
* library.
*
* @since:
* 2.10.0
*/
FT_EXPORT( FT_Error )
FT_Library_SetLcdGeometry( FT_Library library,
FT_Vector sub[3] );
/* */
FT_END_HEADER
#endif /* FTLCDFIL_H_ */
/* END */

View File

@ -1,296 +0,0 @@
/****************************************************************************
*
* ftlist.h
*
* Generic list support for FreeType (specification).
*
* Copyright (C) 1996-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This file implements functions relative to list processing. Its data
* structures are defined in `freetype.h`.
*
*/
#ifndef FTLIST_H_
#define FTLIST_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* list_processing
*
* @title:
* List Processing
*
* @abstract:
* Simple management of lists.
*
* @description:
* This section contains various definitions related to list processing
* using doubly-linked nodes.
*
* @order:
* FT_List
* FT_ListNode
* FT_ListRec
* FT_ListNodeRec
*
* FT_List_Add
* FT_List_Insert
* FT_List_Find
* FT_List_Remove
* FT_List_Up
* FT_List_Iterate
* FT_List_Iterator
* FT_List_Finalize
* FT_List_Destructor
*
*/
/**************************************************************************
*
* @function:
* FT_List_Find
*
* @description:
* Find the list node for a given listed object.
*
* @input:
* list ::
* A pointer to the parent list.
* data ::
* The address of the listed object.
*
* @return:
* List node. `NULL` if it wasn't found.
*/
FT_EXPORT( FT_ListNode )
FT_List_Find( FT_List list,
void* data );
/**************************************************************************
*
* @function:
* FT_List_Add
*
* @description:
* Append an element to the end of a list.
*
* @inout:
* list ::
* A pointer to the parent list.
* node ::
* The node to append.
*/
FT_EXPORT( void )
FT_List_Add( FT_List list,
FT_ListNode node );
/**************************************************************************
*
* @function:
* FT_List_Insert
*
* @description:
* Insert an element at the head of a list.
*
* @inout:
* list ::
* A pointer to parent list.
* node ::
* The node to insert.
*/
FT_EXPORT( void )
FT_List_Insert( FT_List list,
FT_ListNode node );
/**************************************************************************
*
* @function:
* FT_List_Remove
*
* @description:
* Remove a node from a list. This function doesn't check whether the
* node is in the list!
*
* @input:
* node ::
* The node to remove.
*
* @inout:
* list ::
* A pointer to the parent list.
*/
FT_EXPORT( void )
FT_List_Remove( FT_List list,
FT_ListNode node );
/**************************************************************************
*
* @function:
* FT_List_Up
*
* @description:
* Move a node to the head/top of a list. Used to maintain LRU lists.
*
* @inout:
* list ::
* A pointer to the parent list.
* node ::
* The node to move.
*/
FT_EXPORT( void )
FT_List_Up( FT_List list,
FT_ListNode node );
/**************************************************************************
*
* @functype:
* FT_List_Iterator
*
* @description:
* An FT_List iterator function that is called during a list parse by
* @FT_List_Iterate.
*
* @input:
* node ::
* The current iteration list node.
*
* user ::
* A typeless pointer passed to @FT_List_Iterate. Can be used to point
* to the iteration's state.
*/
typedef FT_Error
(*FT_List_Iterator)( FT_ListNode node,
void* user );
/**************************************************************************
*
* @function:
* FT_List_Iterate
*
* @description:
* Parse a list and calls a given iterator function on each element.
* Note that parsing is stopped as soon as one of the iterator calls
* returns a non-zero value.
*
* @input:
* list ::
* A handle to the list.
* iterator ::
* An iterator function, called on each node of the list.
* user ::
* A user-supplied field that is passed as the second argument to the
* iterator.
*
* @return:
* The result (a FreeType error code) of the last iterator call.
*/
FT_EXPORT( FT_Error )
FT_List_Iterate( FT_List list,
FT_List_Iterator iterator,
void* user );
/**************************************************************************
*
* @functype:
* FT_List_Destructor
*
* @description:
* An @FT_List iterator function that is called during a list
* finalization by @FT_List_Finalize to destroy all elements in a given
* list.
*
* @input:
* system ::
* The current system object.
*
* data ::
* The current object to destroy.
*
* user ::
* A typeless pointer passed to @FT_List_Iterate. It can be used to
* point to the iteration's state.
*/
typedef void
(*FT_List_Destructor)( FT_Memory memory,
void* data,
void* user );
/**************************************************************************
*
* @function:
* FT_List_Finalize
*
* @description:
* Destroy all elements in the list as well as the list itself.
*
* @input:
* list ::
* A handle to the list.
*
* destroy ::
* A list destructor that will be applied to each element of the list.
* Set this to `NULL` if not needed.
*
* memory ::
* The current memory object that handles deallocation.
*
* user ::
* A user-supplied field that is passed as the last argument to the
* destructor.
*
* @note:
* This function expects that all nodes added by @FT_List_Add or
* @FT_List_Insert have been dynamically allocated.
*/
FT_EXPORT( void )
FT_List_Finalize( FT_List list,
FT_List_Destructor destroy,
FT_Memory memory,
void* user );
/* */
FT_END_HEADER
#endif /* FTLIST_H_ */
/* END */

View File

@ -1,184 +0,0 @@
/****************************************************************************
*
* ftlogging.h
*
* Additional debugging APIs.
*
* Copyright (C) 2020-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTLOGGING_H_
#define FTLOGGING_H_
#include <ft2build.h>
#include FT_CONFIG_CONFIG_H
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* debugging_apis
*
* @title:
* External Debugging APIs
*
* @abstract:
* Public APIs to control the `FT_DEBUG_LOGGING` macro.
*
* @description:
* This section contains the declarations of public functions that
* enables fine control of what the `FT_DEBUG_LOGGING` macro outputs.
*
*/
/**************************************************************************
*
* @function:
* FT_Trace_Set_Level
*
* @description:
* Change the levels of tracing components of FreeType at run time.
*
* @input:
* tracing_level ::
* New tracing value.
*
* @example:
* The following call makes FreeType trace everything but the 'memory'
* component.
*
* ```
* FT_Trace_Set_Level( "any:7 memory:0 );
* ```
*
* @note:
* This function does nothing if compilation option `FT_DEBUG_LOGGING`
* isn't set.
*
* @since:
* 2.11
*
*/
FT_EXPORT( void )
FT_Trace_Set_Level( const char* tracing_level );
/**************************************************************************
*
* @function:
* FT_Trace_Set_Default_Level
*
* @description:
* Reset tracing value of FreeType's components to the default value
* (i.e., to the value of the `FT2_DEBUG` environment value or to NULL
* if `FT2_DEBUG` is not set).
*
* @note:
* This function does nothing if compilation option `FT_DEBUG_LOGGING`
* isn't set.
*
* @since:
* 2.11
*
*/
FT_EXPORT( void )
FT_Trace_Set_Default_Level( void );
/**************************************************************************
*
* @functype:
* FT_Custom_Log_Handler
*
* @description:
* A function typedef that is used to handle the logging of tracing and
* debug messages on a file system.
*
* @input:
* ft_component ::
* The name of `FT_COMPONENT` from which the current debug or error
* message is produced.
*
* fmt ::
* Actual debug or tracing message.
*
* args::
* Arguments of debug or tracing messages.
*
* @since:
* 2.11
*
*/
typedef void
(*FT_Custom_Log_Handler)( const char* ft_component,
const char* fmt,
va_list args );
/**************************************************************************
*
* @function:
* FT_Set_Log_Handler
*
* @description:
* A function to set a custom log handler.
*
* @input:
* handler ::
* New logging function.
*
* @note:
* This function does nothing if compilation option `FT_DEBUG_LOGGING`
* isn't set.
*
* @since:
* 2.11
*
*/
FT_EXPORT( void )
FT_Set_Log_Handler( FT_Custom_Log_Handler handler );
/**************************************************************************
*
* @function:
* FT_Set_Default_Log_Handler
*
* @description:
* A function to undo the effect of @FT_Set_Log_Handler, resetting the
* log handler to FreeType's built-in version.
*
* @note:
* This function does nothing if compilation option `FT_DEBUG_LOGGING`
* isn't set.
*
* @since:
* 2.11
*
*/
FT_EXPORT( void )
FT_Set_Default_Log_Handler( void );
/* */
FT_END_HEADER
#endif /* FTLOGGING_H_ */
/* END */

View File

@ -1,100 +0,0 @@
/****************************************************************************
*
* ftlzw.h
*
* LZW-compressed stream support.
*
* Copyright (C) 2004-2022 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTLZW_H_
#define FTLZW_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* lzw
*
* @title:
* LZW Streams
*
* @abstract:
* Using LZW-compressed font files.
*
* @description:
* In certain builds of the library, LZW compression recognition is
* automatically handled when calling @FT_New_Face or @FT_Open_Face.
* This means that if no font driver is capable of handling the raw
* compressed file, the library will try to open a LZW stream from it and
* re-open the face with it.
*
* The stream implementation is very basic and resets the decompression
* process each time seeking backwards is needed within the stream,
* which significantly undermines the performance.
*
* This section contains the declaration of LZW-specific functions.
*
*/
/**************************************************************************
*
* @function:
* FT_Stream_OpenLZW
*
* @description:
* Open a new stream to parse LZW-compressed font files. This is mainly
* used to support the compressed `*.pcf.Z` fonts that come with XFree86.
*
* @input:
* stream ::
* The target embedding stream.
*
* source ::
* The source stream.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The source stream must be opened _before_ calling this function.
*
* Calling the internal function `FT_Stream_Close` on the new stream will
* **not** call `FT_Stream_Close` on the source stream. None of the
* stream objects will be released to the heap.
*
* This function may return `FT_Err_Unimplemented_Feature` if your build
* of FreeType was not compiled with LZW support.
*/
FT_EXPORT( FT_Error )
FT_Stream_OpenLZW( FT_Stream stream,
FT_Stream source );
/* */
FT_END_HEADER
#endif /* FTLZW_H_ */
/* END */

View File

@ -1,289 +0,0 @@
/****************************************************************************
*
* ftmac.h
*
* Additional Mac-specific API.
*
* Copyright (C) 1996-2022 by
* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/****************************************************************************
*
* NOTE: Include this file after `FT_FREETYPE_H` and after any
* Mac-specific headers (because this header uses Mac types such as
* 'Handle', 'FSSpec', 'FSRef', etc.)
*
*/
#ifndef FTMAC_H_
#define FTMAC_H_
FT_BEGIN_HEADER
/* gcc-3.1 and later can warn about functions tagged as deprecated */
#ifndef FT_DEPRECATED_ATTRIBUTE
#if defined( __GNUC__ ) && \
( ( __GNUC__ >= 4 ) || \
( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 1 ) ) )
#define FT_DEPRECATED_ATTRIBUTE __attribute__(( deprecated ))
#else
#define FT_DEPRECATED_ATTRIBUTE
#endif
#endif
/**************************************************************************
*
* @section:
* mac_specific
*
* @title:
* Mac Specific Interface
*
* @abstract:
* Only available on the Macintosh.
*
* @description:
* The following definitions are only available if FreeType is compiled
* on a Macintosh.
*
*/
/**************************************************************************
*
* @function:
* FT_New_Face_From_FOND
*
* @description:
* Create a new face object from a FOND resource.
*
* @inout:
* library ::
* A handle to the library resource.
*
* @input:
* fond ::
* A FOND resource.
*
* face_index ::
* Only supported for the -1 'sanity check' special case.
*
* @output:
* aface ::
* A handle to a new face object.
*
* @return:
* FreeType error code. 0~means success.
*
* @example:
* This function can be used to create @FT_Face objects from fonts that
* are installed in the system as follows.
*
* ```
* fond = GetResource( 'FOND', fontName );
* error = FT_New_Face_From_FOND( library, fond, 0, &face );
* ```
*/
FT_EXPORT( FT_Error )
FT_New_Face_From_FOND( FT_Library library,
Handle fond,
FT_Long face_index,
FT_Face *aface )
FT_DEPRECATED_ATTRIBUTE;
/**************************************************************************
*
* @function:
* FT_GetFile_From_Mac_Name
*
* @description:
* Return an FSSpec for the disk file containing the named font.
*
* @input:
* fontName ::
* Mac OS name of the font (e.g., Times New Roman Bold).
*
* @output:
* pathSpec ::
* FSSpec to the file. For passing to @FT_New_Face_From_FSSpec.
*
* face_index ::
* Index of the face. For passing to @FT_New_Face_From_FSSpec.
*
* @return:
* FreeType error code. 0~means success.
*/
FT_EXPORT( FT_Error )
FT_GetFile_From_Mac_Name( const char* fontName,
FSSpec* pathSpec,
FT_Long* face_index )
FT_DEPRECATED_ATTRIBUTE;
/**************************************************************************
*
* @function:
* FT_GetFile_From_Mac_ATS_Name
*
* @description:
* Return an FSSpec for the disk file containing the named font.
*
* @input:
* fontName ::
* Mac OS name of the font in ATS framework.
*
* @output:
* pathSpec ::
* FSSpec to the file. For passing to @FT_New_Face_From_FSSpec.
*
* face_index ::
* Index of the face. For passing to @FT_New_Face_From_FSSpec.
*
* @return:
* FreeType error code. 0~means success.
*/
FT_EXPORT( FT_Error )
FT_GetFile_From_Mac_ATS_Name( const char* fontName,
FSSpec* pathSpec,
FT_Long* face_index )
FT_DEPRECATED_ATTRIBUTE;
/**************************************************************************
*
* @function:
* FT_GetFilePath_From_Mac_ATS_Name
*
* @description:
* Return a pathname of the disk file and face index for given font name
* that is handled by ATS framework.
*
* @input:
* fontName ::
* Mac OS name of the font in ATS framework.
*
* @output:
* path ::
* Buffer to store pathname of the file. For passing to @FT_New_Face.
* The client must allocate this buffer before calling this function.
*
* maxPathSize ::
* Lengths of the buffer `path` that client allocated.
*
* face_index ::
* Index of the face. For passing to @FT_New_Face.
*
* @return:
* FreeType error code. 0~means success.
*/
FT_EXPORT( FT_Error )
FT_GetFilePath_From_Mac_ATS_Name( const char* fontName,
UInt8* path,
UInt32 maxPathSize,
FT_Long* face_index )
FT_DEPRECATED_ATTRIBUTE;
/**************************************************************************
*
* @function:
* FT_New_Face_From_FSSpec
*
* @description:
* Create a new face object from a given resource and typeface index
* using an FSSpec to the font file.
*
* @inout:
* library ::
* A handle to the library resource.
*
* @input:
* spec ::
* FSSpec to the font file.
*
* face_index ::
* The index of the face within the resource. The first face has
* index~0.
* @output:
* aface ::
* A handle to a new face object.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except it
* accepts an FSSpec instead of a path.
*/
FT_EXPORT( FT_Error )
FT_New_Face_From_FSSpec( FT_Library library,
const FSSpec *spec,
FT_Long face_index,
FT_Face *aface )
FT_DEPRECATED_ATTRIBUTE;
/**************************************************************************
*
* @function:
* FT_New_Face_From_FSRef
*
* @description:
* Create a new face object from a given resource and typeface index
* using an FSRef to the font file.
*
* @inout:
* library ::
* A handle to the library resource.
*
* @input:
* spec ::
* FSRef to the font file.
*
* face_index ::
* The index of the face within the resource. The first face has
* index~0.
* @output:
* aface ::
* A handle to a new face object.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* @FT_New_Face_From_FSRef is identical to @FT_New_Face except it accepts
* an FSRef instead of a path.
*/
FT_EXPORT( FT_Error )
FT_New_Face_From_FSRef( FT_Library library,
const FSRef *ref,
FT_Long face_index,
FT_Face *aface )
FT_DEPRECATED_ATTRIBUTE;
/* */
FT_END_HEADER
#endif /* FTMAC_H_ */
/* END */

Some files were not shown because too many files have changed in this diff Show More